* [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.