public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] sched_rt: fix overload bug on rt group scheduling
@ 2009-04-01 16:40 Peter Zijlstra
  2009-04-02  0:58 ` Gregory Haskins
  0 siblings, 1 reply; 8+ messages in thread
From: Peter Zijlstra @ 2009-04-01 16:40 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Gregory Haskins, Steven Rostedt, LKML, Thomas Gleixner

Fixes an easily triggerable BUG() when setting process affinities.

Make sure to count the number of migratable tasks in the same place:
the root rt_rq. Otherwise the number doesn't make sense and we'll hit
the BUG in set_cpus_allowed_rt().

Also, make sure we only count tasks, not groups (this is probably
already taken care of by the fact that rt_se->nr_cpus_allowed will be 0
for groups, but be more explicit)

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Tested-by: Thomas Gleixner <tglx@linutronix.de>
CC: stable@kernel.org
---
 kernel/sched_rt.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index de4469a..c1ee8dc 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -10,6 +10,8 @@ static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se)
 
 #ifdef CONFIG_RT_GROUP_SCHED
 
+#define rt_entity_is_task(rt_se) (!(rt_se)->my_q)
+
 static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
 {
 	return rt_rq->rq;
@@ -22,6 +24,8 @@ static inline struct rt_rq *rt_rq_of_se(struct sched_rt_entity *rt_se)
 
 #else /* CONFIG_RT_GROUP_SCHED */
 
+#define rt_entity_is_task(rt_se) (1)
+
 static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
 {
 	return container_of(rt_rq, struct rq, rt);
@@ -73,7 +77,7 @@ static inline void rt_clear_overload(struct rq *rq)
 
 static void update_rt_migration(struct rt_rq *rt_rq)
 {
-	if (rt_rq->rt_nr_migratory && (rt_rq->rt_nr_running > 1)) {
+	if (rt_rq->rt_nr_migratory > 1) {
 		if (!rt_rq->overloaded) {
 			rt_set_overload(rq_of_rt_rq(rt_rq));
 			rt_rq->overloaded = 1;
@@ -86,6 +90,11 @@ static void update_rt_migration(struct rt_rq *rt_rq)
 
 static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 {
+	if (!rt_entity_is_task(rt_se))
+		return;
+
+	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
+
 	if (rt_se->nr_cpus_allowed > 1)
 		rt_rq->rt_nr_migratory++;
 
@@ -94,6 +103,11 @@ static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 
 static void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 {
+	if (!rt_entity_is_task(rt_se))
+		return;
+
+	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
+
 	if (rt_se->nr_cpus_allowed > 1)
 		rt_rq->rt_nr_migratory--;
 


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] sched_rt: fix overload bug on rt group scheduling
  2009-04-01 16:40 [PATCH] sched_rt: fix overload bug on rt group scheduling Peter Zijlstra
@ 2009-04-02  0:58 ` Gregory Haskins
  2009-04-02  6:48   ` Peter Zijlstra
  0 siblings, 1 reply; 8+ messages in thread
From: Gregory Haskins @ 2009-04-02  0:58 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Ingo Molnar, Steven Rostedt, LKML, Thomas Gleixner

[-- Attachment #1: Type: text/plain, Size: 3485 bytes --]

Hi Peter,

Peter Zijlstra wrote:
> Fixes an easily triggerable BUG() when setting process affinities.
>
> Make sure to count the number of migratable tasks in the same place:
> the root rt_rq. Otherwise the number doesn't make sense and we'll hit
> the BUG in set_cpus_allowed_rt().
>
> Also, make sure we only count tasks, not groups (this is probably
> already taken care of by the fact that rt_se->nr_cpus_allowed will be 0
> for groups, but be more explicit)
>
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Tested-by: Thomas Gleixner <tglx@linutronix.de>
> CC: stable@kernel.org
> ---
>  kernel/sched_rt.c |   16 +++++++++++++++-
>  1 files changed, 15 insertions(+), 1 deletions(-)
>
> diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
> index de4469a..c1ee8dc 100644
> --- a/kernel/sched_rt.c
> +++ b/kernel/sched_rt.c
> @@ -10,6 +10,8 @@ static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se)
>  
>  #ifdef CONFIG_RT_GROUP_SCHED
>  
> +#define rt_entity_is_task(rt_se) (!(rt_se)->my_q)
> +
>  static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
>  {
>  	return rt_rq->rq;
> @@ -22,6 +24,8 @@ static inline struct rt_rq *rt_rq_of_se(struct sched_rt_entity *rt_se)
>  
>  #else /* CONFIG_RT_GROUP_SCHED */
>  
> +#define rt_entity_is_task(rt_se) (1)
> +
>  static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
>  {
>  	return container_of(rt_rq, struct rq, rt);
> @@ -73,7 +77,7 @@ static inline void rt_clear_overload(struct rq *rq)
>  
>  static void update_rt_migration(struct rt_rq *rt_rq)
>  {
> -	if (rt_rq->rt_nr_migratory && (rt_rq->rt_nr_running > 1)) {
> +	if (rt_rq->rt_nr_migratory > 1) {
>   

The rest of the patch is making sense to me, but I am a little concerned
about this change.

The original logic was designed to catch the condition when you might
have a non-migratory task running, and a migratory task queued.   This
would mean nr_running == 2, and nr_migratory == 1, which is eligible for
overload handling.  (Of course, the opposite could be true..the
migratory is running and the non-migratory is queued...we cannot discern
the difference here and we go into overload anyway.  This is just
suboptimal but functionally correct).

What can happen now is you could have that above condition but we will
not go into overload unless there is at least two migratory tasks
queued.  This will undoubtedly allow a potential scheduling latency on
task #2.

I think we really need to qualify overload on both running > 1 and at
least one migratory task.  Is there a way to get this state, even if by
other means?

>  		if (!rt_rq->overloaded) {
>  			rt_set_overload(rq_of_rt_rq(rt_rq));
>  			rt_rq->overloaded = 1;
> @@ -86,6 +90,11 @@ static void update_rt_migration(struct rt_rq *rt_rq)
>  
>  static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
>  {
> +	if (!rt_entity_is_task(rt_se))
> +		return;
> +
> +	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
> +
>  	if (rt_se->nr_cpus_allowed > 1)
>  		rt_rq->rt_nr_migratory++;
>  
> @@ -94,6 +103,11 @@ static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
>  
>  static void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
>  {
> +	if (!rt_entity_is_task(rt_se))
> +		return;
> +
> +	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
> +
>  	if (rt_se->nr_cpus_allowed > 1)
>  		rt_rq->rt_nr_migratory--;
>  
>
>   



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] sched_rt: fix overload bug on rt group scheduling
  2009-04-02  0:58 ` Gregory Haskins
@ 2009-04-02  6:48   ` Peter Zijlstra
  2009-04-02 11:21     ` Gregory Haskins
  0 siblings, 1 reply; 8+ messages in thread
From: Peter Zijlstra @ 2009-04-02  6:48 UTC (permalink / raw)
  To: Gregory Haskins; +Cc: Ingo Molnar, Steven Rostedt, LKML, Thomas Gleixner

On Wed, 2009-04-01 at 20:58 -0400, Gregory Haskins wrote:
> Hi Peter,
> 
> Peter Zijlstra wrote:
> > Fixes an easily triggerable BUG() when setting process affinities.
> >
> > Make sure to count the number of migratable tasks in the same place:
> > the root rt_rq. Otherwise the number doesn't make sense and we'll hit
> > the BUG in set_cpus_allowed_rt().
> >
> > Also, make sure we only count tasks, not groups (this is probably
> > already taken care of by the fact that rt_se->nr_cpus_allowed will be 0
> > for groups, but be more explicit)
> >
> > Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > Tested-by: Thomas Gleixner <tglx@linutronix.de>
> > CC: stable@kernel.org
> > ---
> >  kernel/sched_rt.c |   16 +++++++++++++++-
> >  1 files changed, 15 insertions(+), 1 deletions(-)
> >
> > diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
> > index de4469a..c1ee8dc 100644
> > --- a/kernel/sched_rt.c
> > +++ b/kernel/sched_rt.c
> > @@ -10,6 +10,8 @@ static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se)
> >  
> >  #ifdef CONFIG_RT_GROUP_SCHED
> >  
> > +#define rt_entity_is_task(rt_se) (!(rt_se)->my_q)
> > +
> >  static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
> >  {
> >  	return rt_rq->rq;
> > @@ -22,6 +24,8 @@ static inline struct rt_rq *rt_rq_of_se(struct sched_rt_entity *rt_se)
> >  
> >  #else /* CONFIG_RT_GROUP_SCHED */
> >  
> > +#define rt_entity_is_task(rt_se) (1)
> > +
> >  static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
> >  {
> >  	return container_of(rt_rq, struct rq, rt);
> > @@ -73,7 +77,7 @@ static inline void rt_clear_overload(struct rq *rq)
> >  
> >  static void update_rt_migration(struct rt_rq *rt_rq)
> >  {
> > -	if (rt_rq->rt_nr_migratory && (rt_rq->rt_nr_running > 1)) {
> > +	if (rt_rq->rt_nr_migratory > 1) {
> >   
> 
> The rest of the patch is making sense to me, but I am a little concerned
> about this change.
> 
> The original logic was designed to catch the condition when you might
> have a non-migratory task running, and a migratory task queued.   This
> would mean nr_running == 2, and nr_migratory == 1, which is eligible for
> overload handling.  (Of course, the opposite could be true..the
> migratory is running and the non-migratory is queued...we cannot discern
> the difference here and we go into overload anyway.  This is just
> suboptimal but functionally correct).
> 
> What can happen now is you could have that above condition but we will
> not go into overload unless there is at least two migratory tasks
> queued.  This will undoubtedly allow a potential scheduling latency on
> task #2.
> 
> I think we really need to qualify overload on both running > 1 and at
> least one migratory task.  Is there a way to get this state, even if by
> other means?

Ah, yes, I missed that bit. I ripped out the rt_nr_running because I 1)
didn't think of this, and 2) rt_nr_running is accounted per rt_rq, not
per-cpu, so it doesn't match.

Since rt_nr_running is also used in a per rt_rq setting, changing that
isn't possible and we'd need to introduce another per-cpu variant is you
want to re-instate this.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] sched_rt: fix overload bug on rt group scheduling
  2009-04-02  6:48   ` Peter Zijlstra
@ 2009-04-02 11:21     ` Gregory Haskins
  2009-07-08 15:37       ` [PATCH] sched_rt: fix overload bug on rt group scheduling -v2 Peter Zijlstra
  0 siblings, 1 reply; 8+ messages in thread
From: Gregory Haskins @ 2009-04-02 11:21 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Ingo Molnar, Steven Rostedt, LKML, Thomas Gleixner

[-- Attachment #1: Type: text/plain, Size: 3890 bytes --]

Peter Zijlstra wrote:
> On Wed, 2009-04-01 at 20:58 -0400, Gregory Haskins wrote:
>   
>> Hi Peter,
>>
>> Peter Zijlstra wrote:
>>     
>>> Fixes an easily triggerable BUG() when setting process affinities.
>>>
>>> Make sure to count the number of migratable tasks in the same place:
>>> the root rt_rq. Otherwise the number doesn't make sense and we'll hit
>>> the BUG in set_cpus_allowed_rt().
>>>
>>> Also, make sure we only count tasks, not groups (this is probably
>>> already taken care of by the fact that rt_se->nr_cpus_allowed will be 0
>>> for groups, but be more explicit)
>>>
>>> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
>>> Tested-by: Thomas Gleixner <tglx@linutronix.de>
>>> CC: stable@kernel.org
>>> ---
>>>  kernel/sched_rt.c |   16 +++++++++++++++-
>>>  1 files changed, 15 insertions(+), 1 deletions(-)
>>>
>>> diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
>>> index de4469a..c1ee8dc 100644
>>> --- a/kernel/sched_rt.c
>>> +++ b/kernel/sched_rt.c
>>> @@ -10,6 +10,8 @@ static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se)
>>>  
>>>  #ifdef CONFIG_RT_GROUP_SCHED
>>>  
>>> +#define rt_entity_is_task(rt_se) (!(rt_se)->my_q)
>>> +
>>>  static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
>>>  {
>>>  	return rt_rq->rq;
>>> @@ -22,6 +24,8 @@ static inline struct rt_rq *rt_rq_of_se(struct sched_rt_entity *rt_se)
>>>  
>>>  #else /* CONFIG_RT_GROUP_SCHED */
>>>  
>>> +#define rt_entity_is_task(rt_se) (1)
>>> +
>>>  static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
>>>  {
>>>  	return container_of(rt_rq, struct rq, rt);
>>> @@ -73,7 +77,7 @@ static inline void rt_clear_overload(struct rq *rq)
>>>  
>>>  static void update_rt_migration(struct rt_rq *rt_rq)
>>>  {
>>> -	if (rt_rq->rt_nr_migratory && (rt_rq->rt_nr_running > 1)) {
>>> +	if (rt_rq->rt_nr_migratory > 1) {
>>>   
>>>       
>> The rest of the patch is making sense to me, but I am a little concerned
>> about this change.
>>
>> The original logic was designed to catch the condition when you might
>> have a non-migratory task running, and a migratory task queued.   This
>> would mean nr_running == 2, and nr_migratory == 1, which is eligible for
>> overload handling.  (Of course, the opposite could be true..the
>> migratory is running and the non-migratory is queued...we cannot discern
>> the difference here and we go into overload anyway.  This is just
>> suboptimal but functionally correct).
>>
>> What can happen now is you could have that above condition but we will
>> not go into overload unless there is at least two migratory tasks
>> queued.  This will undoubtedly allow a potential scheduling latency on
>> task #2.
>>
>> I think we really need to qualify overload on both running > 1 and at
>> least one migratory task.  Is there a way to get this state, even if by
>> other means?
>>     
>
> Ah, yes, I missed that bit. I ripped out the rt_nr_running because I 1)
> didn't think of this, and 2) rt_nr_running is accounted per rt_rq, not
> per-cpu, so it doesn't match.
>
> Since rt_nr_running is also used in a per rt_rq setting, changing that
> isn't possible and we'd need to introduce another per-cpu variant is you
> want to re-instate this.
>   
Yeah, I actually don't care if its literally a nr_running stat
reinstated, or some other way to restore "correctness" ;)

Double bonus if you can solve that problem I mentioned above where I
can't tell if its really eligible for overload in all cases (but goes
into overload anyway to be conservative).  I had been thinking of doing
something like subtracting the nr_migration number when a migratory task
is put on the cpu.  But this is kind of messy because you need to handle
all the places that can manipulate nr_migratory to make sure it doesnt
break.

Thanks Peter!
-Greg




[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] sched_rt: fix overload bug on rt group scheduling -v2
  2009-04-02 11:21     ` Gregory Haskins
@ 2009-07-08 15:37       ` Peter Zijlstra
  2009-07-08 15:54         ` Gregory Haskins
                           ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Peter Zijlstra @ 2009-07-08 15:37 UTC (permalink / raw)
  To: Gregory Haskins
  Cc: Ingo Molnar, Steven Rostedt, LKML, Thomas Gleixner, zengzm.kernel

Greg, how's this?

---
Subject: sched_rt: fix overload bug on rt group scheduling
From: Peter Zijlstra <peterz@infradead.org>
Date: Wed, 01 Apr 2009 18:40:15 +0200

Fixes an easily triggerable BUG() when setting process affinities.

Make sure to count the number of migratable tasks in the same place:
the root rt_rq. Otherwise the number doesn't make sense and we'll hit
the BUG in set_cpus_allowed_rt().

Also, make sure we only count tasks, not groups (this is probably
already taken care of by the fact that rt_se->nr_cpus_allowed will be 0
for groups, but be more explicit)

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
 kernel/sched_rt.c |   18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

Index: linux-2.6/kernel/sched_rt.c
===================================================================
--- linux-2.6.orig/kernel/sched_rt.c
+++ linux-2.6/kernel/sched_rt.c
@@ -10,6 +10,8 @@ static inline struct task_struct *rt_tas
 
 #ifdef CONFIG_RT_GROUP_SCHED
 
+#define rt_entity_is_task(rt_se) (!(rt_se)->my_q)
+
 static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
 {
 	return rt_rq->rq;
@@ -22,6 +24,8 @@ static inline struct rt_rq *rt_rq_of_se(
 
 #else /* CONFIG_RT_GROUP_SCHED */
 
+#define rt_entity_is_task(rt_se) (1)
+
 static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
 {
 	return container_of(rt_rq, struct rq, rt);
@@ -73,7 +77,7 @@ static inline void rt_clear_overload(str
 
 static void update_rt_migration(struct rt_rq *rt_rq)
 {
-	if (rt_rq->rt_nr_migratory && (rt_rq->rt_nr_running > 1)) {
+	if (rt_rq->rt_nr_migratory && rt_rq->rt_nr_total > 1) {
 		if (!rt_rq->overloaded) {
 			rt_set_overload(rq_of_rt_rq(rt_rq));
 			rt_rq->overloaded = 1;
@@ -86,6 +90,12 @@ static void update_rt_migration(struct r
 
 static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 {
+	if (!rt_entity_is_task(rt_se))
+		return;
+
+	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
+
+	rt_rq->rt_nr_total++;
 	if (rt_se->nr_cpus_allowed > 1)
 		rt_rq->rt_nr_migratory++;
 
@@ -94,6 +104,12 @@ static void inc_rt_migration(struct sche
 
 static void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 {
+	if (!rt_entity_is_task(rt_se))
+		return;
+
+	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
+
+	rt_rq->rt_nr_total--;
 	if (rt_se->nr_cpus_allowed > 1)
 		rt_rq->rt_nr_migratory--;
 
diff --git a/kernel/sched.c b/kernel/sched.c
index fd3ac58..a07d520 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -493,6 +493,7 @@ struct rt_rq {
 #endif
 #ifdef CONFIG_SMP
 	unsigned long rt_nr_migratory;
+	unsigned long rt_nr_total;
 	int overloaded;
 	struct plist_head pushable_tasks;
 #endif


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] sched_rt: fix overload bug on rt group scheduling -v2
  2009-07-08 15:37       ` [PATCH] sched_rt: fix overload bug on rt group scheduling -v2 Peter Zijlstra
@ 2009-07-08 15:54         ` Gregory Haskins
  2009-07-10  4:05         ` Gregory Haskins
  2009-07-10 10:41         ` [tip:sched/urgent] sched_rt: Fix overload bug on rt group scheduling tip-bot for Peter Zijlstra
  2 siblings, 0 replies; 8+ messages in thread
From: Gregory Haskins @ 2009-07-08 15:54 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Steven Rostedt, LKML, Thomas Gleixner, zengzm.kernel

[-- Attachment #1: Type: text/plain, Size: 146 bytes --]

Peter Zijlstra wrote:
> Greg, how's this?
>   

Quick glance looks reasonable.  I'll try to take a closer look this
afternoon.

-Greg



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 266 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] sched_rt: fix overload bug on rt group scheduling -v2
  2009-07-08 15:37       ` [PATCH] sched_rt: fix overload bug on rt group scheduling -v2 Peter Zijlstra
  2009-07-08 15:54         ` Gregory Haskins
@ 2009-07-10  4:05         ` Gregory Haskins
  2009-07-10 10:41         ` [tip:sched/urgent] sched_rt: Fix overload bug on rt group scheduling tip-bot for Peter Zijlstra
  2 siblings, 0 replies; 8+ messages in thread
From: Gregory Haskins @ 2009-07-10  4:05 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Steven Rostedt, LKML, Thomas Gleixner, zengzm.kernel

[-- Attachment #1: Type: text/plain, Size: 3231 bytes --]

Peter Zijlstra wrote:
> Greg, how's this?
>   

Hi Peter,
  Sorry for the delay getting back to you.

I can't vouch specifically for the rt-group specific part, but as far as
the general balancer modifications to the migration code, it looks good. 

> ---
> Subject: sched_rt: fix overload bug on rt group scheduling
> From: Peter Zijlstra <peterz@infradead.org>
> Date: Wed, 01 Apr 2009 18:40:15 +0200
>
> Fixes an easily triggerable BUG() when setting process affinities.
>
> Make sure to count the number of migratable tasks in the same place:
> the root rt_rq. Otherwise the number doesn't make sense and we'll hit
> the BUG in set_cpus_allowed_rt().
>
> Also, make sure we only count tasks, not groups (this is probably
> already taken care of by the fact that rt_se->nr_cpus_allowed will be 0
> for groups, but be more explicit)
>
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
>   

Acked-by: Gregory Haskins <ghaskins@novell.com>

> ---
>  kernel/sched_rt.c |   18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
> Index: linux-2.6/kernel/sched_rt.c
> ===================================================================
> --- linux-2.6.orig/kernel/sched_rt.c
> +++ linux-2.6/kernel/sched_rt.c
> @@ -10,6 +10,8 @@ static inline struct task_struct *rt_tas
>  
>  #ifdef CONFIG_RT_GROUP_SCHED
>  
> +#define rt_entity_is_task(rt_se) (!(rt_se)->my_q)
> +
>  static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
>  {
>  	return rt_rq->rq;
> @@ -22,6 +24,8 @@ static inline struct rt_rq *rt_rq_of_se(
>  
>  #else /* CONFIG_RT_GROUP_SCHED */
>  
> +#define rt_entity_is_task(rt_se) (1)
> +
>  static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
>  {
>  	return container_of(rt_rq, struct rq, rt);
> @@ -73,7 +77,7 @@ static inline void rt_clear_overload(str
>  
>  static void update_rt_migration(struct rt_rq *rt_rq)
>  {
> -	if (rt_rq->rt_nr_migratory && (rt_rq->rt_nr_running > 1)) {
> +	if (rt_rq->rt_nr_migratory && rt_rq->rt_nr_total > 1) {
>  		if (!rt_rq->overloaded) {
>  			rt_set_overload(rq_of_rt_rq(rt_rq));
>  			rt_rq->overloaded = 1;
> @@ -86,6 +90,12 @@ static void update_rt_migration(struct r
>  
>  static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
>  {
> +	if (!rt_entity_is_task(rt_se))
> +		return;
> +
> +	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
> +
> +	rt_rq->rt_nr_total++;
>  	if (rt_se->nr_cpus_allowed > 1)
>  		rt_rq->rt_nr_migratory++;
>  
> @@ -94,6 +104,12 @@ static void inc_rt_migration(struct sche
>  
>  static void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
>  {
> +	if (!rt_entity_is_task(rt_se))
> +		return;
> +
> +	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
> +
> +	rt_rq->rt_nr_total--;
>  	if (rt_se->nr_cpus_allowed > 1)
>  		rt_rq->rt_nr_migratory--;
>  
> diff --git a/kernel/sched.c b/kernel/sched.c
> index fd3ac58..a07d520 100644
> --- a/kernel/sched.c
> +++ b/kernel/sched.c
> @@ -493,6 +493,7 @@ struct rt_rq {
>  #endif
>  #ifdef CONFIG_SMP
>  	unsigned long rt_nr_migratory;
> +	unsigned long rt_nr_total;
>  	int overloaded;
>  	struct plist_head pushable_tasks;
>  #endif
>
>   



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 266 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [tip:sched/urgent] sched_rt: Fix overload bug on rt group scheduling
  2009-07-08 15:37       ` [PATCH] sched_rt: fix overload bug on rt group scheduling -v2 Peter Zijlstra
  2009-07-08 15:54         ` Gregory Haskins
  2009-07-10  4:05         ` Gregory Haskins
@ 2009-07-10 10:41         ` tip-bot for Peter Zijlstra
  2 siblings, 0 replies; 8+ messages in thread
From: tip-bot for Peter Zijlstra @ 2009-07-10 10:41 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, a.p.zijlstra, peterz, ghaskins, tglx,
	mingo

Commit-ID:  a1ba4d8ba9f06a397e97cbd67a93ee306860b40a
Gitweb:     http://git.kernel.org/tip/a1ba4d8ba9f06a397e97cbd67a93ee306860b40a
Author:     Peter Zijlstra <peterz@infradead.org>
AuthorDate: Wed, 1 Apr 2009 18:40:15 +0200
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Fri, 10 Jul 2009 10:43:29 +0200

sched_rt: Fix overload bug on rt group scheduling

Fixes an easily triggerable BUG() when setting process affinities.

Make sure to count the number of migratable tasks in the same place:
the root rt_rq. Otherwise the number doesn't make sense and we'll hit
the BUG in set_cpus_allowed_rt().

Also, make sure we only count tasks, not groups (this is probably
already taken care of by the fact that rt_se->nr_cpus_allowed will be 0
for groups, but be more explicit)

Tested-by: Thomas Gleixner <tglx@linutronix.de>
CC: stable@kernel.org
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Gregory Haskins <ghaskins@novell.com>
LKML-Reference: <1247067476.9777.57.camel@twins>
Signed-off-by: Ingo Molnar <mingo@elte.hu>


---
 kernel/sched.c    |    1 +
 kernel/sched_rt.c |   18 +++++++++++++++++-
 2 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/kernel/sched.c b/kernel/sched.c
index 7c9098d..a17f3d9 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -493,6 +493,7 @@ struct rt_rq {
 #endif
 #ifdef CONFIG_SMP
 	unsigned long rt_nr_migratory;
+	unsigned long rt_nr_total;
 	int overloaded;
 	struct plist_head pushable_tasks;
 #endif
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 9bf0d2a..3918e01 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -10,6 +10,8 @@ static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se)
 
 #ifdef CONFIG_RT_GROUP_SCHED
 
+#define rt_entity_is_task(rt_se) (!(rt_se)->my_q)
+
 static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
 {
 	return rt_rq->rq;
@@ -22,6 +24,8 @@ static inline struct rt_rq *rt_rq_of_se(struct sched_rt_entity *rt_se)
 
 #else /* CONFIG_RT_GROUP_SCHED */
 
+#define rt_entity_is_task(rt_se) (1)
+
 static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
 {
 	return container_of(rt_rq, struct rq, rt);
@@ -73,7 +77,7 @@ static inline void rt_clear_overload(struct rq *rq)
 
 static void update_rt_migration(struct rt_rq *rt_rq)
 {
-	if (rt_rq->rt_nr_migratory && (rt_rq->rt_nr_running > 1)) {
+	if (rt_rq->rt_nr_migratory && rt_rq->rt_nr_total > 1) {
 		if (!rt_rq->overloaded) {
 			rt_set_overload(rq_of_rt_rq(rt_rq));
 			rt_rq->overloaded = 1;
@@ -86,6 +90,12 @@ static void update_rt_migration(struct rt_rq *rt_rq)
 
 static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 {
+	if (!rt_entity_is_task(rt_se))
+		return;
+
+	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
+
+	rt_rq->rt_nr_total++;
 	if (rt_se->nr_cpus_allowed > 1)
 		rt_rq->rt_nr_migratory++;
 
@@ -94,6 +104,12 @@ static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 
 static void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 {
+	if (!rt_entity_is_task(rt_se))
+		return;
+
+	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
+
+	rt_rq->rt_nr_total--;
 	if (rt_se->nr_cpus_allowed > 1)
 		rt_rq->rt_nr_migratory--;
 

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2009-07-10 10:42 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-01 16:40 [PATCH] sched_rt: fix overload bug on rt group scheduling Peter Zijlstra
2009-04-02  0:58 ` Gregory Haskins
2009-04-02  6:48   ` Peter Zijlstra
2009-04-02 11:21     ` Gregory Haskins
2009-07-08 15:37       ` [PATCH] sched_rt: fix overload bug on rt group scheduling -v2 Peter Zijlstra
2009-07-08 15:54         ` Gregory Haskins
2009-07-10  4:05         ` Gregory Haskins
2009-07-10 10:41         ` [tip:sched/urgent] sched_rt: Fix overload bug on rt group scheduling tip-bot for Peter Zijlstra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox