* [patch 2/2] sched: Protect sched_rr_get_param access to task->sched_class
@ 2009-12-08 20:24 Thomas Gleixner
2009-12-09 8:00 ` Peter Zijlstra
0 siblings, 1 reply; 7+ messages in thread
From: Thomas Gleixner @ 2009-12-08 20:24 UTC (permalink / raw)
To: LKML; +Cc: Ingo Molnar, Peter Zijlstra
[-- Attachment #1: sched-fix-sched-get-rr-param-race.patch --]
[-- Type: text/plain, Size: 988 bytes --]
sched_rr_get_param calls task->sched_class->get_rr_interval(task)
without protection against a concurrent sched_setscheduler() call
which modifies task->sched_class.
Serialize the access with task_rq_lock(task);
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/sched.c | 4 ++++
1 file changed, 4 insertions(+)
Index: linux-2.6-tip/kernel/sched.c
===================================================================
--- linux-2.6-tip.orig/kernel/sched.c
+++ linux-2.6-tip/kernel/sched.c
@@ -6887,6 +6887,8 @@ SYSCALL_DEFINE2(sched_rr_get_interval, p
{
struct task_struct *p;
unsigned int time_slice;
+ unsigned long flags;
+ struct rq *rq;
int retval;
struct timespec t;
@@ -6903,7 +6905,9 @@ SYSCALL_DEFINE2(sched_rr_get_interval, p
if (retval)
goto out_unlock;
+ rq = task_rq_lock(p, &flags);
time_slice = p->sched_class->get_rr_interval(p);
+ task_rq_unlock(rq, &flags);
read_unlock(&tasklist_lock);
jiffies_to_timespec(time_slice, &t);
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [patch 2/2] sched: Protect sched_rr_get_param access to task->sched_class 2009-12-08 20:24 [patch 2/2] sched: Protect sched_rr_get_param access to task->sched_class Thomas Gleixner @ 2009-12-09 8:00 ` Peter Zijlstra 2009-12-09 8:03 ` Peter Zijlstra 0 siblings, 1 reply; 7+ messages in thread From: Peter Zijlstra @ 2009-12-09 8:00 UTC (permalink / raw) To: Thomas Gleixner; +Cc: LKML, Ingo Molnar On Tue, 2009-12-08 at 20:24 +0000, Thomas Gleixner wrote: > plain text document attachment > (sched-fix-sched-get-rr-param-race.patch) > sched_rr_get_param calls task->sched_class->get_rr_interval(task) > without protection against a concurrent sched_setscheduler() call > which modifies task->sched_class. > > Serialize the access with task_rq_lock(task); > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de> > --- > kernel/sched.c | 4 ++++ > 1 file changed, 4 insertions(+) > > Index: linux-2.6-tip/kernel/sched.c > =================================================================== > --- linux-2.6-tip.orig/kernel/sched.c > +++ linux-2.6-tip/kernel/sched.c > @@ -6887,6 +6887,8 @@ SYSCALL_DEFINE2(sched_rr_get_interval, p > { > struct task_struct *p; > unsigned int time_slice; > + unsigned long flags; > + struct rq *rq; > int retval; > struct timespec t; > > @@ -6903,7 +6905,9 @@ SYSCALL_DEFINE2(sched_rr_get_interval, p > if (retval) > goto out_unlock; > > + rq = task_rq_lock(p, &flags); > time_slice = p->sched_class->get_rr_interval(p); > + task_rq_unlock(rq, &flags); > > read_unlock(&tasklist_lock); > jiffies_to_timespec(time_slice, &t); > Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [patch 2/2] sched: Protect sched_rr_get_param access to task->sched_class 2009-12-09 8:00 ` Peter Zijlstra @ 2009-12-09 8:03 ` Peter Zijlstra 2009-12-09 8:06 ` Thomas Gleixner 0 siblings, 1 reply; 7+ messages in thread From: Peter Zijlstra @ 2009-12-09 8:03 UTC (permalink / raw) To: Thomas Gleixner; +Cc: LKML, Ingo Molnar On Wed, 2009-12-09 at 09:00 +0100, Peter Zijlstra wrote: > On Tue, 2009-12-08 at 20:24 +0000, Thomas Gleixner wrote: > > plain text document attachment > > (sched-fix-sched-get-rr-param-race.patch) > > sched_rr_get_param calls task->sched_class->get_rr_interval(task) > > without protection against a concurrent sched_setscheduler() call > > which modifies task->sched_class. > > > > Serialize the access with task_rq_lock(task); > > > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de> > > --- > > kernel/sched.c | 4 ++++ > > 1 file changed, 4 insertions(+) > > > > Index: linux-2.6-tip/kernel/sched.c > > =================================================================== > > --- linux-2.6-tip.orig/kernel/sched.c > > +++ linux-2.6-tip/kernel/sched.c > > @@ -6887,6 +6887,8 @@ SYSCALL_DEFINE2(sched_rr_get_interval, p > > { > > struct task_struct *p; > > unsigned int time_slice; > > + unsigned long flags; > > + struct rq *rq; > > int retval; > > struct timespec t; > > > > @@ -6903,7 +6905,9 @@ SYSCALL_DEFINE2(sched_rr_get_interval, p > > if (retval) > > goto out_unlock; > > > > + rq = task_rq_lock(p, &flags); > > time_slice = p->sched_class->get_rr_interval(p); > > + task_rq_unlock(rq, &flags); > > > > read_unlock(&tasklist_lock); > > jiffies_to_timespec(time_slice, &t); > > > > Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Oh, that was too quick, get_rr_interval_fair() actually takes the rq->lock, so lets add this: unsigned int get_rr_interval_fair(struct task_struct *task) { struct sched_entity *se = &task->se; - unsigned long flags; - struct rq *rq; unsigned int rr_interval = 0; /* * Time slice is 0 for SCHED_OTHER tasks that are on an otherwise * idle runqueue: */ - rq = task_rq_lock(task, &flags); if (rq->cfs.load.weight) rr_interval = NS_TO_JIFFIES(sched_slice(&rq->cfs, se)); - task_rq_unlock(rq, &flags); - return rr_interval; } ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [patch 2/2] sched: Protect sched_rr_get_param access to task->sched_class 2009-12-09 8:03 ` Peter Zijlstra @ 2009-12-09 8:06 ` Thomas Gleixner 2009-12-09 8:32 ` [patch V2 " Thomas Gleixner 0 siblings, 1 reply; 7+ messages in thread From: Thomas Gleixner @ 2009-12-09 8:06 UTC (permalink / raw) To: Peter Zijlstra; +Cc: LKML, Ingo Molnar On Wed, 9 Dec 2009, Peter Zijlstra wrote: > On Wed, 2009-12-09 at 09:00 +0100, Peter Zijlstra wrote: > > On Tue, 2009-12-08 at 20:24 +0000, Thomas Gleixner wrote: > > > plain text document attachment > > > (sched-fix-sched-get-rr-param-race.patch) > > > sched_rr_get_param calls task->sched_class->get_rr_interval(task) > > > without protection against a concurrent sched_setscheduler() call > > > which modifies task->sched_class. > > > > > > Serialize the access with task_rq_lock(task); > > > > > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de> > > > --- > > > kernel/sched.c | 4 ++++ > > > 1 file changed, 4 insertions(+) > > > > > > Index: linux-2.6-tip/kernel/sched.c > > > =================================================================== > > > --- linux-2.6-tip.orig/kernel/sched.c > > > +++ linux-2.6-tip/kernel/sched.c > > > @@ -6887,6 +6887,8 @@ SYSCALL_DEFINE2(sched_rr_get_interval, p > > > { > > > struct task_struct *p; > > > unsigned int time_slice; > > > + unsigned long flags; > > > + struct rq *rq; > > > int retval; > > > struct timespec t; > > > > > > @@ -6903,7 +6905,9 @@ SYSCALL_DEFINE2(sched_rr_get_interval, p > > > if (retval) > > > goto out_unlock; > > > > > > + rq = task_rq_lock(p, &flags); > > > time_slice = p->sched_class->get_rr_interval(p); > > > + task_rq_unlock(rq, &flags); > > > > > > read_unlock(&tasklist_lock); > > > jiffies_to_timespec(time_slice, &t); > > > > > > > Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> > > Oh, that was too quick, get_rr_interval_fair() actually takes the > rq->lock, so lets add this: > > unsigned int get_rr_interval_fair(struct task_struct *task) > { > struct sched_entity *se = &task->se; > - unsigned long flags; > - struct rq *rq; > unsigned int rr_interval = 0; > > /* > * Time slice is 0 for SCHED_OTHER tasks that are on an otherwise > * idle runqueue: > */ > - rq = task_rq_lock(task, &flags); > if (rq->cfs.load.weight) > rr_interval = NS_TO_JIFFIES(sched_slice(&rq->cfs, se)); > - task_rq_unlock(rq, &flags); > - > return rr_interval; > } Duh, yes. I looked at that actually and made a mental note to remove it. :( Thanks for catching that, tglx ^ permalink raw reply [flat|nested] 7+ messages in thread
* [patch V2 sched: Protect sched_rr_get_param access to task->sched_class 2009-12-09 8:06 ` Thomas Gleixner @ 2009-12-09 8:32 ` Thomas Gleixner 2009-12-09 8:33 ` Peter Zijlstra 2009-12-09 9:53 ` [tip:sched/urgent] sched: Protect sched_rr_get_param() " tip-bot for Thomas Gleixner 0 siblings, 2 replies; 7+ messages in thread From: Thomas Gleixner @ 2009-12-09 8:32 UTC (permalink / raw) To: Peter Zijlstra; +Cc: LKML, Ingo Molnar sched_rr_get_param calls task->sched_class->get_rr_interval(task) without protection against a concurrent sched_setscheduler() call which modifies task->sched_class. Serialize the access with task_rq_lock(task) and hand the rq pointer into get_rr_interval() as it's needed at least in the sched_fair implementation. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- include/linux/sched.h | 3 ++- kernel/sched.c | 6 +++++- kernel/sched_fair.c | 6 +----- kernel/sched_idletask.c | 2 +- kernel/sched_rt.c | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) Index: linux-2.6-tip/include/linux/sched.h =================================================================== --- linux-2.6-tip.orig/include/linux/sched.h +++ linux-2.6-tip/include/linux/sched.h @@ -1111,7 +1111,8 @@ struct sched_class { void (*prio_changed) (struct rq *this_rq, struct task_struct *task, int oldprio, int running); - unsigned int (*get_rr_interval) (struct task_struct *task); + unsigned int (*get_rr_interval) (struct rq *rq, + struct task_struct *task); #ifdef CONFIG_FAIR_GROUP_SCHED void (*moved_group) (struct task_struct *p); Index: linux-2.6-tip/kernel/sched.c =================================================================== --- linux-2.6-tip.orig/kernel/sched.c +++ linux-2.6-tip/kernel/sched.c @@ -6887,6 +6887,8 @@ SYSCALL_DEFINE2(sched_rr_get_interval, p { struct task_struct *p; unsigned int time_slice; + unsigned long flags; + struct rq *rq; int retval; struct timespec t; @@ -6903,7 +6905,9 @@ SYSCALL_DEFINE2(sched_rr_get_interval, p if (retval) goto out_unlock; - time_slice = p->sched_class->get_rr_interval(p); + rq = task_rq_lock(p, &flags); + time_slice = p->sched_class->get_rr_interval(rq, p); + task_rq_unlock(rq, &flags); read_unlock(&tasklist_lock); jiffies_to_timespec(time_slice, &t); Index: linux-2.6-tip/kernel/sched_fair.c =================================================================== --- linux-2.6-tip.orig/kernel/sched_fair.c +++ linux-2.6-tip/kernel/sched_fair.c @@ -2014,21 +2014,17 @@ static void moved_group_fair(struct task } #endif -unsigned int get_rr_interval_fair(struct task_struct *task) +unsigned int get_rr_interval_fair(struct rq *rq, struct task_struct *task) { struct sched_entity *se = &task->se; - unsigned long flags; - struct rq *rq; unsigned int rr_interval = 0; /* * Time slice is 0 for SCHED_OTHER tasks that are on an otherwise * idle runqueue: */ - rq = task_rq_lock(task, &flags); if (rq->cfs.load.weight) rr_interval = NS_TO_JIFFIES(sched_slice(&rq->cfs, se)); - task_rq_unlock(rq, &flags); return rr_interval; } Index: linux-2.6-tip/kernel/sched_idletask.c =================================================================== --- linux-2.6-tip.orig/kernel/sched_idletask.c +++ linux-2.6-tip/kernel/sched_idletask.c @@ -97,7 +97,7 @@ static void prio_changed_idle(struct rq check_preempt_curr(rq, p, 0); } -unsigned int get_rr_interval_idle(struct task_struct *task) +unsigned int get_rr_interval_idle(struct rq *rq, struct task_struct *task) { return 0; } Index: linux-2.6-tip/kernel/sched_rt.c =================================================================== --- linux-2.6-tip.orig/kernel/sched_rt.c +++ linux-2.6-tip/kernel/sched_rt.c @@ -1721,7 +1721,7 @@ static void set_curr_task_rt(struct rq * dequeue_pushable_task(rq, p); } -unsigned int get_rr_interval_rt(struct task_struct *task) +unsigned int get_rr_interval_rt(struct rq *rq, struct task_struct *task) { /* * Time slice is 0 for SCHED_FIFO tasks ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [patch V2 sched: Protect sched_rr_get_param access to task->sched_class 2009-12-09 8:32 ` [patch V2 " Thomas Gleixner @ 2009-12-09 8:33 ` Peter Zijlstra 2009-12-09 9:53 ` [tip:sched/urgent] sched: Protect sched_rr_get_param() " tip-bot for Thomas Gleixner 1 sibling, 0 replies; 7+ messages in thread From: Peter Zijlstra @ 2009-12-09 8:33 UTC (permalink / raw) To: Thomas Gleixner; +Cc: LKML, Ingo Molnar On Wed, 2009-12-09 at 09:32 +0100, Thomas Gleixner wrote: > sched_rr_get_param calls task->sched_class->get_rr_interval(task) > without protection against a concurrent sched_setscheduler() call > which modifies task->sched_class. > > Serialize the access with task_rq_lock(task) and hand the rq pointer > into get_rr_interval() as it's needed at least in the sched_fair > implementation. > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> ^ permalink raw reply [flat|nested] 7+ messages in thread
* [tip:sched/urgent] sched: Protect sched_rr_get_param() access to task->sched_class 2009-12-09 8:32 ` [patch V2 " Thomas Gleixner 2009-12-09 8:33 ` Peter Zijlstra @ 2009-12-09 9:53 ` tip-bot for Thomas Gleixner 1 sibling, 0 replies; 7+ messages in thread From: tip-bot for Thomas Gleixner @ 2009-12-09 9:53 UTC (permalink / raw) To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, peterz, tglx, mingo Commit-ID: dba091b9e3522b9d32fc9975e48d3b69633b45f0 Gitweb: http://git.kernel.org/tip/dba091b9e3522b9d32fc9975e48d3b69633b45f0 Author: Thomas Gleixner <tglx@linutronix.de> AuthorDate: Wed, 9 Dec 2009 09:32:03 +0100 Committer: Ingo Molnar <mingo@elte.hu> CommitDate: Wed, 9 Dec 2009 10:01:07 +0100 sched: Protect sched_rr_get_param() access to task->sched_class sched_rr_get_param calls task->sched_class->get_rr_interval(task) without protection against a concurrent sched_setscheduler() call which modifies task->sched_class. Serialize the access with task_rq_lock(task) and hand the rq pointer into get_rr_interval() as it's needed at least in the sched_fair implementation. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Peter Zijlstra <peterz@infradead.org> LKML-Reference: <alpine.LFD.2.00.0912090930120.3089@localhost.localdomain> Signed-off-by: Ingo Molnar <mingo@elte.hu> --- include/linux/sched.h | 3 ++- kernel/sched.c | 6 +++++- kernel/sched_fair.c | 6 +----- kernel/sched_idletask.c | 2 +- kernel/sched_rt.c | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 89115ec..9b24027 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1111,7 +1111,8 @@ struct sched_class { void (*prio_changed) (struct rq *this_rq, struct task_struct *task, int oldprio, int running); - unsigned int (*get_rr_interval) (struct task_struct *task); + unsigned int (*get_rr_interval) (struct rq *rq, + struct task_struct *task); #ifdef CONFIG_FAIR_GROUP_SCHED void (*moved_group) (struct task_struct *p); diff --git a/kernel/sched.c b/kernel/sched.c index c4635f7..68db5a2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6887,6 +6887,8 @@ SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid, { struct task_struct *p; unsigned int time_slice; + unsigned long flags; + struct rq *rq; int retval; struct timespec t; @@ -6903,7 +6905,9 @@ SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid, if (retval) goto out_unlock; - time_slice = p->sched_class->get_rr_interval(p); + rq = task_rq_lock(p, &flags); + time_slice = p->sched_class->get_rr_interval(rq, p); + task_rq_unlock(rq, &flags); read_unlock(&tasklist_lock); jiffies_to_timespec(time_slice, &t); diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index f61837a..613c1c7 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -2014,21 +2014,17 @@ static void moved_group_fair(struct task_struct *p) } #endif -unsigned int get_rr_interval_fair(struct task_struct *task) +unsigned int get_rr_interval_fair(struct rq *rq, struct task_struct *task) { struct sched_entity *se = &task->se; - unsigned long flags; - struct rq *rq; unsigned int rr_interval = 0; /* * Time slice is 0 for SCHED_OTHER tasks that are on an otherwise * idle runqueue: */ - rq = task_rq_lock(task, &flags); if (rq->cfs.load.weight) rr_interval = NS_TO_JIFFIES(sched_slice(&rq->cfs, se)); - task_rq_unlock(rq, &flags); return rr_interval; } diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c index b133a28..33d5384 100644 --- a/kernel/sched_idletask.c +++ b/kernel/sched_idletask.c @@ -97,7 +97,7 @@ static void prio_changed_idle(struct rq *rq, struct task_struct *p, check_preempt_curr(rq, p, 0); } -unsigned int get_rr_interval_idle(struct task_struct *task) +unsigned int get_rr_interval_idle(struct rq *rq, struct task_struct *task) { return 0; } diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 5c5fef3..aecbd9c 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -1721,7 +1721,7 @@ static void set_curr_task_rt(struct rq *rq) dequeue_pushable_task(rq, p); } -unsigned int get_rr_interval_rt(struct task_struct *task) +unsigned int get_rr_interval_rt(struct rq *rq, struct task_struct *task) { /* * Time slice is 0 for SCHED_FIFO tasks ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-12-09 9:53 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-12-08 20:24 [patch 2/2] sched: Protect sched_rr_get_param access to task->sched_class Thomas Gleixner 2009-12-09 8:00 ` Peter Zijlstra 2009-12-09 8:03 ` Peter Zijlstra 2009-12-09 8:06 ` Thomas Gleixner 2009-12-09 8:32 ` [patch V2 " Thomas Gleixner 2009-12-09 8:33 ` Peter Zijlstra 2009-12-09 9:53 ` [tip:sched/urgent] sched: Protect sched_rr_get_param() " tip-bot for Thomas Gleixner
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.