linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt()
@ 2011-12-01 21:26 Kirill Tkhai
  2011-12-20 17:44 ` Oleg Nesterov
  2012-02-13 17:23 ` Steven Rostedt
  0 siblings, 2 replies; 12+ messages in thread
From: Kirill Tkhai @ 2011-12-01 21:26 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Peter Zijlstra, tkhai

[PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable
tasks in set_cpus_allowed_rt()

Migration status depends on a difference of weight from 0 and 1. If
weight > 1 (<= 1) and old weight <= 1 (> 1) then task becomes pushable
(not pushable). We are not insterested in exact values of it, is it 3 or
4, for example.

Now if we are changing affinity from a set of 3 cpus to a set of 4, the
task will be dequeued and enqueued sequentially without important
difference in comparison with initial state. The only difference is in
internal representation of plist queue of pushable tasks and the fact
that the task may won't be the first in a sequence of the same priority
tasks. But it seems to me it gives nothing.

Signed-off-by: Tkhai Kirill <tkhai@yandex.ru>

--- kernel/sched_rt.c.orig	2011-12-02 00:29:11.970243145 +0400
+++ kernel/sched_rt.c	2011-12-02 00:37:43.622846606 +0400
@@ -1572,43 +1572,37 @@ static void set_cpus_allowed_rt(struct t
 				const struct cpumask *new_mask)
 {
 	int weight = cpumask_weight(new_mask);
+	struct rq *rq;
 
 	BUG_ON(!rt_task(p));
 
 	/*
-	 * Update the migration status of the RQ if we have an RT task
-	 * which is running AND changing its weight value.
+	 * Just exit if it's not necessary to change migration status
 	 */
-	if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
-		struct rq *rq = task_rq(p);
+	if ((p->rt.nr_cpus_allowed <= 1 && weight <= 1)
+		|| (p->rt.nr_cpus_allowed > 1 && weight > 1))
+		return;
 
-		if (!task_current(rq, p)) {
-			/*
-			 * Make sure we dequeue this task from the pushable list
-			 * before going further.  It will either remain off of
-			 * the list because we are no longer pushable, or it
-			 * will be requeued.
-			 */
-			if (p->rt.nr_cpus_allowed > 1)
-				dequeue_pushable_task(rq, p);
-
-			/*
-			 * Requeue if our weight is changing and still > 1
-			 */
-			if (weight > 1)
-				enqueue_pushable_task(rq, p);
-
-		}
-
-		if ((p->rt.nr_cpus_allowed <= 1) && (weight > 1)) {
-			rq->rt.rt_nr_migratory++;
-		} else if ((p->rt.nr_cpus_allowed > 1) && (weight <= 1)) {
-			BUG_ON(!rq->rt.rt_nr_migratory);
-			rq->rt.rt_nr_migratory--;
-		}
+	if (!p->on_rq)
+		return;
 
-		update_rt_migration(&rq->rt);
+	rq = task_rq(p);
+
+	/*
+	 * Several cpus were allowed but now it's not so OR vice versa
+	 */
+	if (weight <= 1) {
+		if (!task_current(rq, p))
+			dequeue_pushable_task(rq, p);
+		BUG_ON(!rq->rt.rt_nr_migratory);
+		rq->rt.rt_nr_migratory--;
+	} else {
+		if (!task_current(rq, p))
+			enqueue_pushable_task(rq, p);
+		rq->rt.rt_nr_migratory++;
 	}
+
+	update_rt_migration(&rq->rt);
 }
 
 /* Assumes rq->lock is held */




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

* Re: [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt()
  2011-12-01 21:26 [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt() Kirill Tkhai
@ 2011-12-20 17:44 ` Oleg Nesterov
  2011-12-20 20:28   ` Tkhai Kirill
  2012-02-13 17:23 ` Steven Rostedt
  1 sibling, 1 reply; 12+ messages in thread
From: Oleg Nesterov @ 2011-12-20 17:44 UTC (permalink / raw)
  To: Kirill Tkhai; +Cc: linux-kernel, Ingo Molnar, Peter Zijlstra, Gregory Haskins

On 12/02, Kirill Tkhai wrote:
>
> Migration status depends on a difference of weight from 0 and 1. If
> weight > 1 (<= 1) and old weight <= 1 (> 1) then task becomes pushable
> (not pushable). We are not insterested in exact values of it, is it 3 or
> 4, for example.
>
> Now if we are changing affinity from a set of 3 cpus to a set of 4, the
> task will be dequeued and enqueued sequentially without important
> difference in comparison with initial state. The only difference is in
> internal representation of plist queue of pushable tasks and the fact
> that the task may won't be the first in a sequence of the same priority
> tasks. But it seems to me it gives nothing.

Looks reasonable, although I can't say I really understand this code.
Add Gregory.

> Signed-off-by: Tkhai Kirill <tkhai@yandex.ru>
>
> --- kernel/sched_rt.c.orig	2011-12-02 00:29:11.970243145 +0400
> +++ kernel/sched_rt.c	2011-12-02 00:37:43.622846606 +0400

please use -p1

> @@ -1572,43 +1572,37 @@ static void set_cpus_allowed_rt(struct t
>  				const struct cpumask *new_mask)
>  {
>  	int weight = cpumask_weight(new_mask);
> +	struct rq *rq;
>  
>  	BUG_ON(!rt_task(p));
>  
>  	/*
> -	 * Update the migration status of the RQ if we have an RT task
> -	 * which is running AND changing its weight value.
> +	 * Just exit if it's not necessary to change migration status
>  	 */
> -	if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
> -		struct rq *rq = task_rq(p);
> +	if ((p->rt.nr_cpus_allowed <= 1 && weight <= 1)
> +		|| (p->rt.nr_cpus_allowed > 1 && weight > 1))
> +		return;

Subjective, but may be

	if ((p->rt.nr_cpus_allowed > 1) != (weight > 1))
		return;

looks more understandable?

> -		if (!task_current(rq, p)) {
> -			/*
> -			 * Make sure we dequeue this task from the pushable list
> -			 * before going further.  It will either remain off of
> -			 * the list because we are no longer pushable, or it
> -			 * will be requeued.
> -			 */
> -			if (p->rt.nr_cpus_allowed > 1)
> -				dequeue_pushable_task(rq, p);
> -
> -			/*
> -			 * Requeue if our weight is changing and still > 1
> -			 */
> -			if (weight > 1)
> -				enqueue_pushable_task(rq, p);
> -
> -		}
> -
> -		if ((p->rt.nr_cpus_allowed <= 1) && (weight > 1)) {
> -			rq->rt.rt_nr_migratory++;
> -		} else if ((p->rt.nr_cpus_allowed > 1) && (weight <= 1)) {
> -			BUG_ON(!rq->rt.rt_nr_migratory);
> -			rq->rt.rt_nr_migratory--;
> -		}
> +	if (!p->on_rq)
> +		return;
>  
> -		update_rt_migration(&rq->rt);
> +	rq = task_rq(p);
> +
> +	/*
> +	 * Several cpus were allowed but now it's not so OR vice versa
> +	 */
> +	if (weight <= 1) {
> +		if (!task_current(rq, p))
> +			dequeue_pushable_task(rq, p);
> +		BUG_ON(!rq->rt.rt_nr_migratory);
> +		rq->rt.rt_nr_migratory--;
> +	} else {
> +		if (!task_current(rq, p))
> +			enqueue_pushable_task(rq, p);
> +		rq->rt.rt_nr_migratory++;
>  	}
> +
> +	update_rt_migration(&rq->rt);
>  }
>  
>  /* Assumes rq->lock is held */
> 
> 
> 


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

* Re: [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt()
  2011-12-20 17:44 ` Oleg Nesterov
@ 2011-12-20 20:28   ` Tkhai Kirill
  2011-12-20 21:09     ` Tkhai Kirill
  0 siblings, 1 reply; 12+ messages in thread
From: Tkhai Kirill @ 2011-12-20 20:28 UTC (permalink / raw)
  To: Oleg Nesterov; +Cc: linux-kernel, Ingo Molnar, Peter Zijlstra, Gregory Haskins

20.12.2011, 21:44, "Oleg Nesterov" <oleg@redhat.com>:
> On 12/02, Kirill Tkhai wrote:
>
>>  Migration status depends on a difference of weight from 0 and 1. If
>>  weight > 1 (<= 1) and old weight <= 1 (> 1) then task becomes pushable
>>  (not pushable). We are not insterested in exact values of it, is it 3 or
>>  4, for example.
>>
>>  Now if we are changing affinity from a set of 3 cpus to a set of 4, the
>>  task will be dequeued and enqueued sequentially without important
>>  difference in comparison with initial state. The only difference is in
>>  internal representation of plist queue of pushable tasks and the fact
>>  that the task may won't be the first in a sequence of the same priority
>>  tasks. But it seems to me it gives nothing.
>
> Looks reasonable, although I can't say I really understand this code.
> Add Gregory.
>
>>  Signed-off-by: Tkhai Kirill <tkhai@yandex.ru>
>>
>>  --- kernel/sched_rt.c.orig 2011-12-02 00:29:11.970243145 +0400
>>  +++ kernel/sched_rt.c 2011-12-02 00:37:43.622846606 +0400
>
> please use -p1
>

Sorry, this time I'm sending "git diffed" output.

>>  @@ -1572,43 +1572,37 @@ static void set_cpus_allowed_rt(struct t
>>                                   const struct cpumask *new_mask)
>>   {
>>           int weight = cpumask_weight(new_mask);
>>  + struct rq *rq;
>>
>>           BUG_ON(!rt_task(p));
>>
>>           /*
>>  - * Update the migration status of the RQ if we have an RT task
>>  - * which is running AND changing its weight value.
>>  + * Just exit if it's not necessary to change migration status
>>            */
>>  - if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
>>  - struct rq *rq = task_rq(p);
>>  + if ((p->rt.nr_cpus_allowed <= 1 && weight <= 1)
>>  + || (p->rt.nr_cpus_allowed > 1 && weight > 1))
>>  + return;
>
> Subjective, but may be
>
>         if ((p->rt.nr_cpus_allowed > 1) != (weight > 1))
>                 return;
>
> looks more understandable?

Yes, thanks.

---

diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 3640ebb..4467f4d 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1774,43 +1774,36 @@ static void set_cpus_allowed_rt(struct task_struct *p,
 				const struct cpumask *new_mask)
 {
 	int weight = cpumask_weight(new_mask);
+	struct rq *rq;
 
 	BUG_ON(!rt_task(p));
 
 	/*
-	 * Update the migration status of the RQ if we have an RT task
-	 * which is running AND changing its weight value.
+	 * Just exit if it's not necessary to change migration status
 	 */
-	if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
-		struct rq *rq = task_rq(p);
-
-		if (!task_current(rq, p)) {
-			/*
-			 * Make sure we dequeue this task from the pushable list
-			 * before going further.  It will either remain off of
-			 * the list because we are no longer pushable, or it
-			 * will be requeued.
-			 */
-			if (p->rt.nr_cpus_allowed > 1)
-				dequeue_pushable_task(rq, p);
-
-			/*
-			 * Requeue if our weight is changing and still > 1
-			 */
-			if (weight > 1)
-				enqueue_pushable_task(rq, p);
+	if ((p->rt.nr_cpus_allowed > 1) != (weight > 1))
+		return;
 
-		}
+	if (!p->on_rq)
+		return;
 
-		if ((p->rt.nr_cpus_allowed <= 1) && (weight > 1)) {
-			rq->rt.rt_nr_migratory++;
-		} else if ((p->rt.nr_cpus_allowed > 1) && (weight <= 1)) {
-			BUG_ON(!rq->rt.rt_nr_migratory);
-			rq->rt.rt_nr_migratory--;
-		}
+	rq = task_rq(p);
 
-		update_rt_migration(&rq->rt);
+	/*
+	 * Several cpus were allowed but now it's not so OR vice versa
+	 */
+	if (weight <= 1) {
+		if (!task_current(rq, p))
+			dequeue_pushable_task(rq, p);
+		BUG_ON(!rq->rt.rt_nr_migratory);
+		rq->rt.rt_nr_migratory--;
+	} else {
+		if (!task_current(rq, p))
+			enqueue_pushable_task(rq, p);
+		rq->rt.rt_nr_migratory++;
 	}
+
+	update_rt_migration(&rq->rt);
 }
 
 /* Assumes rq->lock is held */

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

* Re: [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt()
  2011-12-20 20:28   ` Tkhai Kirill
@ 2011-12-20 21:09     ` Tkhai Kirill
  0 siblings, 0 replies; 12+ messages in thread
From: Tkhai Kirill @ 2011-12-20 21:09 UTC (permalink / raw)
  To: Oleg Nesterov; +Cc: linux-kernel, Ingo Molnar, Peter Zijlstra, Gregory Haskins

Again, right patch

21.12.2011, 00:28, "Tkhai Kirill" <tkhai@yandex.ru>:
> 20.12.2011, 21:44, "Oleg Nesterov" <oleg@redhat.com>:
>
>>  On 12/02, Kirill Tkhai wrote:
>>>   Migration status depends on a difference of weight from 0 and 1. If
>>>   weight > 1 (<= 1) and old weight <= 1 (> 1) then task becomes pushable
>>>   (not pushable). We are not insterested in exact values of it, is it 3 or
>>>   4, for example.
>>>
>>>   Now if we are changing affinity from a set of 3 cpus to a set of 4, the
>>>   task will be dequeued and enqueued sequentially without important
>>>   difference in comparison with initial state. The only difference is in
>>>   internal representation of plist queue of pushable tasks and the fact
>>>   that the task may won't be the first in a sequence of the same priority
>>>   tasks. But it seems to me it gives nothing.
>>  Looks reasonable, although I can't say I really understand this code.
>>  Add Gregory.
>>>   Signed-off-by: Tkhai Kirill <tkhai@yandex.ru>
>>>
>>>   --- kernel/sched_rt.c.orig 2011-12-02 00:29:11.970243145 +0400
>>>   +++ kernel/sched_rt.c 2011-12-02 00:37:43.622846606 +0400
>>  please use -p1
>
> Sorry, this time I'm sending "git diffed" output.
>
>>>   @@ -1572,43 +1572,37 @@ static void set_cpus_allowed_rt(struct t
>>>                                    const struct cpumask *new_mask)
>>>    {
>>>            int weight = cpumask_weight(new_mask);
>>>   + struct rq *rq;
>>>
>>>            BUG_ON(!rt_task(p));
>>>
>>>            /*
>>>   - * Update the migration status of the RQ if we have an RT task
>>>   - * which is running AND changing its weight value.
>>>   + * Just exit if it's not necessary to change migration status
>>>             */
>>>   - if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
>>>   - struct rq *rq = task_rq(p);
>>>   + if ((p->rt.nr_cpus_allowed <= 1 && weight <= 1)
>>>   + || (p->rt.nr_cpus_allowed > 1 && weight > 1))
>>>   + return;
>>  Subjective, but may be
>>
>>          if ((p->rt.nr_cpus_allowed > 1) != (weight > 1))
>>                  return;
>>
>>  looks more understandable?
>
> Yes, thanks.
>
> ---
>
> diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
> index 3640ebb..4467f4d 100644
> --- a/kernel/sched/rt.c
> +++ b/kernel/sched/rt.c
> @@ -1774,43 +1774,36 @@ static void set_cpus_allowed_rt(struct task_struct *p,
>                                  const struct cpumask *new_mask)
>  {
>          int weight = cpumask_weight(new_mask);
> + struct rq *rq;
>
>          BUG_ON(!rt_task(p));
>
>          /*
> - * Update the migration status of the RQ if we have an RT task
> - * which is running AND changing its weight value.
> + * Just exit if it's not necessary to change migration status
>           */
> - if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
> - struct rq *rq = task_rq(p);
> -
> - if (!task_current(rq, p)) {
> - /*
> - * Make sure we dequeue this task from the pushable list
> - * before going further.  It will either remain off of
> - * the list because we are no longer pushable, or it
> - * will be requeued.
> - */
> - if (p->rt.nr_cpus_allowed > 1)
> - dequeue_pushable_task(rq, p);
> -
> - /*
> - * Requeue if our weight is changing and still > 1
> - */
> - if (weight > 1)
> - enqueue_pushable_task(rq, p);
> + if ((p->rt.nr_cpus_allowed > 1) != (weight > 1))
> + return;
>
> - }
> + if (!p->on_rq)
> + return;
>
> - if ((p->rt.nr_cpus_allowed <= 1) && (weight > 1)) {
> - rq->rt.rt_nr_migratory++;
> - } else if ((p->rt.nr_cpus_allowed > 1) && (weight <= 1)) {
> - BUG_ON(!rq->rt.rt_nr_migratory);
> - rq->rt.rt_nr_migratory--;
> - }
> + rq = task_rq(p);
>
> - update_rt_migration(&rq->rt);
> + /*
> + * Several cpus were allowed but now it's not so OR vice versa
> + */
> + if (weight <= 1) {
> + if (!task_current(rq, p))
> + dequeue_pushable_task(rq, p);
> + BUG_ON(!rq->rt.rt_nr_migratory);
> + rq->rt.rt_nr_migratory--;
> + } else {
> + if (!task_current(rq, p))
> + enqueue_pushable_task(rq, p);
> + rq->rt.rt_nr_migratory++;
>          }
> +
> + update_rt_migration(&rq->rt);
>  }
>
>  /* Assumes rq->lock is held */

---

diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 3640ebb..bf48343 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1774,43 +1774,36 @@ static void set_cpus_allowed_rt(struct task_struct *p,
 				const struct cpumask *new_mask)
 {
 	int weight = cpumask_weight(new_mask);
+	struct rq *rq;
 
 	BUG_ON(!rt_task(p));
 
 	/*
-	 * Update the migration status of the RQ if we have an RT task
-	 * which is running AND changing its weight value.
+	 * Just exit if it's not necessary to change migration status
 	 */
-	if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
-		struct rq *rq = task_rq(p);
-
-		if (!task_current(rq, p)) {
-			/*
-			 * Make sure we dequeue this task from the pushable list
-			 * before going further.  It will either remain off of
-			 * the list because we are no longer pushable, or it
-			 * will be requeued.
-			 */
-			if (p->rt.nr_cpus_allowed > 1)
-				dequeue_pushable_task(rq, p);
-
-			/*
-			 * Requeue if our weight is changing and still > 1
-			 */
-			if (weight > 1)
-				enqueue_pushable_task(rq, p);
+	if ((p->rt.nr_cpus_allowed > 1) == (weight > 1))
+		return;
 
-		}
+	if (!p->on_rq)
+		return;
 
-		if ((p->rt.nr_cpus_allowed <= 1) && (weight > 1)) {
-			rq->rt.rt_nr_migratory++;
-		} else if ((p->rt.nr_cpus_allowed > 1) && (weight <= 1)) {
-			BUG_ON(!rq->rt.rt_nr_migratory);
-			rq->rt.rt_nr_migratory--;
-		}
+	rq = task_rq(p);
 
-		update_rt_migration(&rq->rt);
+	/*
+	 * Several cpus were allowed but now it's not so OR vice versa
+	 */
+	if (weight <= 1) {
+		if (!task_current(rq, p))
+			dequeue_pushable_task(rq, p);
+		BUG_ON(!rq->rt.rt_nr_migratory);
+		rq->rt.rt_nr_migratory--;
+	} else {
+		if (!task_current(rq, p))
+			enqueue_pushable_task(rq, p);
+		rq->rt.rt_nr_migratory++;
 	}
+
+	update_rt_migration(&rq->rt);
 }
 
 /* Assumes rq->lock is held */

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

* Re: [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt()
  2011-12-01 21:26 [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt() Kirill Tkhai
  2011-12-20 17:44 ` Oleg Nesterov
@ 2012-02-13 17:23 ` Steven Rostedt
  2012-02-19 14:17   ` Kirill Tkhai
  1 sibling, 1 reply; 12+ messages in thread
From: Steven Rostedt @ 2012-02-13 17:23 UTC (permalink / raw)
  To: Kirill Tkhai; +Cc: linux-kernel, Ingo Molnar, Peter Zijlstra

I wasn't on the Cc of the original message, but it was bounced to me
awhile ago. I'm cleaning out my email and came across it.

Can you send me the latest version of this patch, either against latest
Linus, or against tip/master.

Thanks,

-- Steve

P.S. I'll be at ELC this week so it may not get processed right away.


On Fri, Dec 02, 2011 at 01:26:05AM +0400, Kirill Tkhai wrote:
> [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable
> tasks in set_cpus_allowed_rt()
> 
> Migration status depends on a difference of weight from 0 and 1. If
> weight > 1 (<= 1) and old weight <= 1 (> 1) then task becomes pushable
> (not pushable). We are not insterested in exact values of it, is it 3 or
> 4, for example.
> 
> Now if we are changing affinity from a set of 3 cpus to a set of 4, the
> task will be dequeued and enqueued sequentially without important
> difference in comparison with initial state. The only difference is in
> internal representation of plist queue of pushable tasks and the fact
> that the task may won't be the first in a sequence of the same priority
> tasks. But it seems to me it gives nothing.
> 
> Signed-off-by: Tkhai Kirill <tkhai@yandex.ru>
> 
> --- kernel/sched_rt.c.orig	2011-12-02 00:29:11.970243145 +0400
> +++ kernel/sched_rt.c	2011-12-02 00:37:43.622846606 +0400
> @@ -1572,43 +1572,37 @@ static void set_cpus_allowed_rt(struct t
>  				const struct cpumask *new_mask)
>  {
>  	int weight = cpumask_weight(new_mask);
> +	struct rq *rq;
>  
>  	BUG_ON(!rt_task(p));
>  
>  	/*
> -	 * Update the migration status of the RQ if we have an RT task
> -	 * which is running AND changing its weight value.
> +	 * Just exit if it's not necessary to change migration status
>  	 */
> -	if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
> -		struct rq *rq = task_rq(p);
> +	if ((p->rt.nr_cpus_allowed <= 1 && weight <= 1)
> +		|| (p->rt.nr_cpus_allowed > 1 && weight > 1))
> +		return;
>  
> -		if (!task_current(rq, p)) {
> -			/*
> -			 * Make sure we dequeue this task from the pushable list
> -			 * before going further.  It will either remain off of
> -			 * the list because we are no longer pushable, or it
> -			 * will be requeued.
> -			 */
> -			if (p->rt.nr_cpus_allowed > 1)
> -				dequeue_pushable_task(rq, p);
> -
> -			/*
> -			 * Requeue if our weight is changing and still > 1
> -			 */
> -			if (weight > 1)
> -				enqueue_pushable_task(rq, p);
> -
> -		}
> -
> -		if ((p->rt.nr_cpus_allowed <= 1) && (weight > 1)) {
> -			rq->rt.rt_nr_migratory++;
> -		} else if ((p->rt.nr_cpus_allowed > 1) && (weight <= 1)) {
> -			BUG_ON(!rq->rt.rt_nr_migratory);
> -			rq->rt.rt_nr_migratory--;
> -		}
> +	if (!p->on_rq)
> +		return;
>  
> -		update_rt_migration(&rq->rt);
> +	rq = task_rq(p);
> +
> +	/*
> +	 * Several cpus were allowed but now it's not so OR vice versa
> +	 */
> +	if (weight <= 1) {
> +		if (!task_current(rq, p))
> +			dequeue_pushable_task(rq, p);
> +		BUG_ON(!rq->rt.rt_nr_migratory);
> +		rq->rt.rt_nr_migratory--;
> +	} else {
> +		if (!task_current(rq, p))
> +			enqueue_pushable_task(rq, p);
> +		rq->rt.rt_nr_migratory++;
>  	}
> +
> +	update_rt_migration(&rq->rt);
>  }
>  
>  /* Assumes rq->lock is held */
> 
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

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

* Re: [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt()
  2012-02-13 17:23 ` Steven Rostedt
@ 2012-02-19 14:17   ` Kirill Tkhai
  2012-03-16 23:58     ` Kirill Tkhai
  2012-04-10 15:52     ` Steven Rostedt
  0 siblings, 2 replies; 12+ messages in thread
From: Kirill Tkhai @ 2012-02-19 14:17 UTC (permalink / raw)
  To: Steven Rostedt; +Cc: linux-kernel, Ingo Molnar, Peter Zijlstra

13.02.2012, 21:23, "Steven Rostedt" <rostedt@goodmis.org>:
> I wasn't on the Cc of the original message, but it was bounced to me
> awhile ago. I'm cleaning out my email and came across it.
>
> Can you send me the latest version of this patch, either against latest
> Linus, or against tip/master.
>
> Thanks,
>
> -- Steve
>
> P.S. I'll be at ELC this week so it may not get processed right away.
>

Migration status depends on a difference of weight from 0 and 1.
If weight > 1 (<= 1) and old weight <= 1 (> 1) then task becomes
pushable (or not pushable). We are not insterested in its exact
values, is it 3 or 4, for example.

Now if we are changing affinity from a set of 3 cpus to a set of 4, the-
task will be dequeued and enqueued sequentially without important
difference in comparison with initial state. The only difference is in
internal representation of plist queue of pushable tasks and the fact
that the task may won't be the first in a sequence of the same priority
tasks. But it seems to me it gives nothing.

Signed-off-by: Tkhai Kirill <tkhai@yandex.ru>
---

diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 3640ebb..bf48343 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1779,43 +1779,36 @@ static void set_cpus_allowed_rt(struct task_struct *p,
 				const struct cpumask *new_mask)
 {
 	int weight = cpumask_weight(new_mask);
+	struct rq *rq;
 
 	BUG_ON(!rt_task(p));
 
 	/*
-	 * Update the migration status of the RQ if we have an RT task
-	 * which is running AND changing its weight value.
+	 * Just exit if it's not necessary to change migration status
 	 */
-	if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
-		struct rq *rq = task_rq(p);
-
-		if (!task_current(rq, p)) {
-			/*
-			 * Make sure we dequeue this task from the pushable list
-			 * before going further.  It will either remain off of
-			 * the list because we are no longer pushable, or it
-			 * will be requeued.
-			 */
-			if (p->rt.nr_cpus_allowed > 1)
-				dequeue_pushable_task(rq, p);
-
-			/*
-			 * Requeue if our weight is changing and still > 1
-			 */
-			if (weight > 1)
-				enqueue_pushable_task(rq, p);
+	if ((p->rt.nr_cpus_allowed > 1) == (weight > 1))
+		return;
 
-		}
+	if (!p->on_rq)
+		return;
 
-		if ((p->rt.nr_cpus_allowed <= 1) && (weight > 1)) {
-			rq->rt.rt_nr_migratory++;
-		} else if ((p->rt.nr_cpus_allowed > 1) && (weight <= 1)) {
-			BUG_ON(!rq->rt.rt_nr_migratory);
-			rq->rt.rt_nr_migratory--;
-		}
+	rq = task_rq(p);
 
-		update_rt_migration(&rq->rt);
+	/*
+	 * Several cpus were allowed but now it's not so OR vice versa
+	 */
+	if (weight <= 1) {
+		if (!task_current(rq, p))
+			dequeue_pushable_task(rq, p);
+		BUG_ON(!rq->rt.rt_nr_migratory);
+		rq->rt.rt_nr_migratory--;
+	} else {
+		if (!task_current(rq, p))
+			enqueue_pushable_task(rq, p);
+		rq->rt.rt_nr_migratory++;
 	}
+
+	update_rt_migration(&rq->rt);
 }
 
 /* Assumes rq->lock is held */

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

* Re: [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt()
  2012-02-19 14:17   ` Kirill Tkhai
@ 2012-03-16 23:58     ` Kirill Tkhai
  2012-04-10 13:58       ` Steven Rostedt
  2012-04-10 15:52     ` Steven Rostedt
  1 sibling, 1 reply; 12+ messages in thread
From: Kirill Tkhai @ 2012-03-16 23:58 UTC (permalink / raw)
  To: Steven Rostedt; +Cc: linux-kernel, Ingo Molnar, Peter Zijlstra

Steven, what is about the patch from my previous message? Is everything ok?

Regards,
Kirill

19.02.2012, 18:17, "Kirill Tkhai" <tkhai@yandex.ru>:
> 13.02.2012, 21:23, "Steven Rostedt" <rostedt@goodmis.org>:
>
>>  I wasn't on the Cc of the original message, but it was bounced to me
>>  awhile ago. I'm cleaning out my email and came across it.
>>
>>  Can you send me the latest version of this patch, either against latest
>>  Linus, or against tip/master.
>>
>>  Thanks,
>>
>>  -- Steve
>>
>>  P.S. I'll be at ELC this week so it may not get processed right away.
>
> Migration status depends on a difference of weight from 0 and 1.
> If weight > 1 (<= 1) and old weight <= 1 (> 1) then task becomes
> pushable (or not pushable). We are not insterested in its exact
> values, is it 3 or 4, for example.
>
> Now if we are changing affinity from a set of 3 cpus to a set of 4, the-
> task will be dequeued and enqueued sequentially without important
> difference in comparison with initial state. The only difference is in
> internal representation of plist queue of pushable tasks and the fact
> that the task may won't be the first in a sequence of the same priority
> tasks. But it seems to me it gives nothing.
>
> Signed-off-by: Tkhai Kirill <tkhai@yandex.ru>

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

* Re: [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt()
  2012-03-16 23:58     ` Kirill Tkhai
@ 2012-04-10 13:58       ` Steven Rostedt
  0 siblings, 0 replies; 12+ messages in thread
From: Steven Rostedt @ 2012-04-10 13:58 UTC (permalink / raw)
  To: Kirill Tkhai; +Cc: linux-kernel, Ingo Molnar, Peter Zijlstra

On Sat, 2012-03-17 at 03:58 +0400, Kirill Tkhai wrote:
> Steven, what is about the patch from my previous message? Is everything ok?

You're timing is impeccable. I was in Chemnitz, Germany when you sent
this, and it too was lost in the noise ;-)

I'll take a look at it today.

Thanks!

-- Steve

 
> 
> Regards,
> Kirill
> 
> 19.02.2012, 18:17, "Kirill Tkhai" <tkhai@yandex.ru>:
> > 13.02.2012, 21:23, "Steven Rostedt" <rostedt@goodmis.org>:
> >
> >>  I wasn't on the Cc of the original message, but it was bounced to me
> >>  awhile ago. I'm cleaning out my email and came across it.
> >>
> >>  Can you send me the latest version of this patch, either against latest
> >>  Linus, or against tip/master.
> >>
> >>  Thanks,
> >>
> >>  -- Steve
> >>
> >>  P.S. I'll be at ELC this week so it may not get processed right away.
> >
> > Migration status depends on a difference of weight from 0 and 1.
> > If weight > 1 (<= 1) and old weight <= 1 (> 1) then task becomes
> > pushable (or not pushable). We are not insterested in its exact
> > values, is it 3 or 4, for example.
> >
> > Now if we are changing affinity from a set of 3 cpus to a set of 4, the-
> > task will be dequeued and enqueued sequentially without important
> > difference in comparison with initial state. The only difference is in
> > internal representation of plist queue of pushable tasks and the fact
> > that the task may won't be the first in a sequence of the same priority
> > tasks. But it seems to me it gives nothing.
> >
> > Signed-off-by: Tkhai Kirill <tkhai@yandex.ru>



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

* Re: [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt()
  2012-02-19 14:17   ` Kirill Tkhai
  2012-03-16 23:58     ` Kirill Tkhai
@ 2012-04-10 15:52     ` Steven Rostedt
  2012-04-11  5:06       ` Kirill Tkhai
  1 sibling, 1 reply; 12+ messages in thread
From: Steven Rostedt @ 2012-04-10 15:52 UTC (permalink / raw)
  To: Kirill Tkhai; +Cc: linux-kernel, Ingo Molnar, Peter Zijlstra

On Sun, 2012-02-19 at 18:17 +0400, Kirill Tkhai wrote:
> ---
> 
> diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
> index 3640ebb..bf48343 100644
> --- a/kernel/sched/rt.c
> +++ b/kernel/sched/rt.c
> @@ -1779,43 +1779,36 @@ static void set_cpus_allowed_rt(struct task_struct *p,
>  				const struct cpumask *new_mask)
>  {
>  	int weight = cpumask_weight(new_mask);

Lets move the assignment of weight down. Gcc may optimize, but I don't
want to rely on it.

> +	struct rq *rq;
>  
>  	BUG_ON(!rt_task(p));
>  
>  	/*
> -	 * Update the migration status of the RQ if we have an RT task
> -	 * which is running AND changing its weight value.
> +	 * Just exit if it's not necessary to change migration status

Let's comment this better. Something like:

	Only update if the process changes its state from whether it
	can migrate or not.


>  	 */
> -	if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
> -		struct rq *rq = task_rq(p);
> -
> -		if (!task_current(rq, p)) {
> -			/*
> -			 * Make sure we dequeue this task from the pushable list
> -			 * before going further.  It will either remain off of
> -			 * the list because we are no longer pushable, or it
> -			 * will be requeued.
> -			 */
> -			if (p->rt.nr_cpus_allowed > 1)
> -				dequeue_pushable_task(rq, p);
> -
> -			/*
> -			 * Requeue if our weight is changing and still > 1
> -			 */
> -			if (weight > 1)
> -				enqueue_pushable_task(rq, p);
> +	if ((p->rt.nr_cpus_allowed > 1) == (weight > 1))
> +		return;
>  
> -		}
> +	if (!p->on_rq)
> +		return;

Make the on_rq check first, and move the weight calculation below it.
Why calculate the weight if we don't plan on doing anything with it?

>  
> -		if ((p->rt.nr_cpus_allowed <= 1) && (weight > 1)) {
> -			rq->rt.rt_nr_migratory++;
> -		} else if ((p->rt.nr_cpus_allowed > 1) && (weight <= 1)) {
> -			BUG_ON(!rq->rt.rt_nr_migratory);
> -			rq->rt.rt_nr_migratory--;
> -		}
> +	rq = task_rq(p);
>  
> -		update_rt_migration(&rq->rt);
> +	/*
> +	 * Several cpus were allowed but now it's not so OR vice versa

I rather say:

	The process use to be able to migrate OR it can now migrate

Otherwise, the patch looks good.

Thanks,

-- Steve

P.S. I don't have any more trips in the near future, so I should be much
quicker in my responses ;-)



> +	 */
> +	if (weight <= 1) {
> +		if (!task_current(rq, p))
> +			dequeue_pushable_task(rq, p);
> +		BUG_ON(!rq->rt.rt_nr_migratory);
> +		rq->rt.rt_nr_migratory--;
> +	} else {
> +		if (!task_current(rq, p))
> +			enqueue_pushable_task(rq, p);
> +		rq->rt.rt_nr_migratory++;
>  	}
> +
> +	update_rt_migration(&rq->rt);
>  }
>  
>  /* Assumes rq->lock is held */



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

* Re: [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt()
  2012-04-10 15:52     ` Steven Rostedt
@ 2012-04-11  5:06       ` Kirill Tkhai
  2012-04-14 18:22         ` [tip:sched/core] sched_rt: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt () tip-bot for Kirill Tkhai
  0 siblings, 1 reply; 12+ messages in thread
From: Kirill Tkhai @ 2012-04-11  5:06 UTC (permalink / raw)
  To: Steven Rostedt; +Cc: linux-kernel, Ingo Molnar, Peter Zijlstra

Migration status depends on a difference of weight from 0 and 1.
If weight > 1 (<= 1) and old weight <= 1 (> 1) then task becomes
pushable (or not pushable). We are not insterested in its exact
values, is it 3 or 4, for example.
Now if we are changing affinity from a set of 3 cpus to a set of 4, the-
task will be dequeued and enqueued sequentially without important
difference in comparison with initial state. The only difference is in
internal representation of plist queue of pushable tasks and the fact
that the task may won't be the first in a sequence of the same priority
tasks. But it seems to me it gives nothing.

Signed-off-by: Tkhai Kirill <tkhai@yandex.ru>
---
 kernel/sched/rt.c |   56 ++++++++++++++++++++++++----------------------------
 1 files changed, 26 insertions(+), 30 deletions(-)
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 44af55e..c5565c3 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1803,44 +1803,40 @@ static void task_woken_rt(struct rq *rq, struct task_struct *p)
 static void set_cpus_allowed_rt(struct task_struct *p,
 				const struct cpumask *new_mask)
 {
-	int weight = cpumask_weight(new_mask);
+	struct rq *rq;
+	int weight;
 
 	BUG_ON(!rt_task(p));
 
-	/*
-	 * Update the migration status of the RQ if we have an RT task
-	 * which is running AND changing its weight value.
-	 */
-	if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
-		struct rq *rq = task_rq(p);
-
-		if (!task_current(rq, p)) {
-			/*
-			 * Make sure we dequeue this task from the pushable list
-			 * before going further.  It will either remain off of
-			 * the list because we are no longer pushable, or it
-			 * will be requeued.
-			 */
-			if (p->rt.nr_cpus_allowed > 1)
-				dequeue_pushable_task(rq, p);
+	if (!p->on_rq)
+		return;
 
-			/*
-			 * Requeue if our weight is changing and still > 1
-			 */
-			if (weight > 1)
-				enqueue_pushable_task(rq, p);
+	weight = cpumask_weight(new_mask);
 
-		}
+	/*
+	 * Only update if the process changes its state from whether it
+	 * can migrate or not.
+	 */
+	if ((p->rt.nr_cpus_allowed > 1) == (weight > 1))
+		return;
 
-		if ((p->rt.nr_cpus_allowed <= 1) && (weight > 1)) {
-			rq->rt.rt_nr_migratory++;
-		} else if ((p->rt.nr_cpus_allowed > 1) && (weight <= 1)) {
-			BUG_ON(!rq->rt.rt_nr_migratory);
-			rq->rt.rt_nr_migratory--;
-		}
+	rq = task_rq(p);
 
-		update_rt_migration(&rq->rt);
+	/*
+	 * The process used to be able to migrate OR it can now migrate
+	 */
+	if (weight <= 1) {
+		if (!task_current(rq, p))
+			dequeue_pushable_task(rq, p);
+		BUG_ON(!rq->rt.rt_nr_migratory);
+		rq->rt.rt_nr_migratory--;
+	} else {
+		if (!task_current(rq, p))
+			enqueue_pushable_task(rq, p);
+		rq->rt.rt_nr_migratory++;
 	}
+
+	update_rt_migration(&rq->rt);
 }
 
 /* Assumes rq->lock is held */

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

* [tip:sched/core] sched_rt: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt ()
  2012-04-11  5:06       ` Kirill Tkhai
@ 2012-04-14 18:22         ` tip-bot for Kirill Tkhai
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot for Kirill Tkhai @ 2012-04-14 18:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rostedt, peterz, tkhai, tglx, mingo

Commit-ID:  8d3d5ada56a692d36a9d55858881147ec10cfeb6
Gitweb:     http://git.kernel.org/tip/8d3d5ada56a692d36a9d55858881147ec10cfeb6
Author:     Kirill Tkhai <tkhai@yandex.ru>
AuthorDate: Wed, 11 Apr 2012 09:06:04 +0400
Committer:  Steven Rostedt <rostedt@goodmis.org>
CommitDate: Thu, 12 Apr 2012 16:59:37 -0400

sched_rt: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt()

Migration status depends on a difference of weight from 0 and 1.
If weight > 1 (<= 1) and old weight <= 1 (> 1) then task becomes
pushable (or not pushable). We are not insterested in its exact
values, is it 3 or 4, for example.
Now if we are changing affinity from a set of 3 cpus to a set of 4, the-
task will be dequeued and enqueued sequentially without important
difference in comparison with initial state. The only difference is in
internal representation of plist queue of pushable tasks and the fact
that the task may won't be the first in a sequence of the same priority
tasks. But it seems to me it gives nothing.

Link: http://lkml.kernel.org/r/273741334120764@web83.yandex.ru

Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Tkhai Kirill <tkhai@yandex.ru>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/sched/rt.c |   56 ++++++++++++++++++++++++----------------------------
 1 files changed, 26 insertions(+), 30 deletions(-)

diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index b60dad7..90607a9 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1803,44 +1803,40 @@ static void task_woken_rt(struct rq *rq, struct task_struct *p)
 static void set_cpus_allowed_rt(struct task_struct *p,
 				const struct cpumask *new_mask)
 {
-	int weight = cpumask_weight(new_mask);
+	struct rq *rq;
+	int weight;
 
 	BUG_ON(!rt_task(p));
 
-	/*
-	 * Update the migration status of the RQ if we have an RT task
-	 * which is running AND changing its weight value.
-	 */
-	if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
-		struct rq *rq = task_rq(p);
-
-		if (!task_current(rq, p)) {
-			/*
-			 * Make sure we dequeue this task from the pushable list
-			 * before going further.  It will either remain off of
-			 * the list because we are no longer pushable, or it
-			 * will be requeued.
-			 */
-			if (p->rt.nr_cpus_allowed > 1)
-				dequeue_pushable_task(rq, p);
+	if (!p->on_rq)
+		return;
 
-			/*
-			 * Requeue if our weight is changing and still > 1
-			 */
-			if (weight > 1)
-				enqueue_pushable_task(rq, p);
+	weight = cpumask_weight(new_mask);
 
-		}
+	/*
+	 * Only update if the process changes its state from whether it
+	 * can migrate or not.
+	 */
+	if ((p->rt.nr_cpus_allowed > 1) == (weight > 1))
+		return;
 
-		if ((p->rt.nr_cpus_allowed <= 1) && (weight > 1)) {
-			rq->rt.rt_nr_migratory++;
-		} else if ((p->rt.nr_cpus_allowed > 1) && (weight <= 1)) {
-			BUG_ON(!rq->rt.rt_nr_migratory);
-			rq->rt.rt_nr_migratory--;
-		}
+	rq = task_rq(p);
 
-		update_rt_migration(&rq->rt);
+	/*
+	 * The process used to be able to migrate OR it can now migrate
+	 */
+	if (weight <= 1) {
+		if (!task_current(rq, p))
+			dequeue_pushable_task(rq, p);
+		BUG_ON(!rq->rt.rt_nr_migratory);
+		rq->rt.rt_nr_migratory--;
+	} else {
+		if (!task_current(rq, p))
+			enqueue_pushable_task(rq, p);
+		rq->rt.rt_nr_migratory++;
 	}
+
+	update_rt_migration(&rq->rt);
 }
 
 /* Assumes rq->lock is held */

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

* [PATCH] sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt()
@ 2012-01-11 19:10 Kirill Tkhai
  0 siblings, 0 replies; 12+ messages in thread
From: Kirill Tkhai @ 2012-01-11 19:10 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Peter Zijlstra, Mike Galbraith, kirill.tkhai

Migration status depends on a difference of weight from 0 and 1. If
weight > 1 (<= 1) and old weight <= 1 (> 1) then task becomes pushable
(not pushable). We are not insterested in exact values of it, is it 3 or
4, for example.

Now, if we are changing affinity from a set of 3 cpus to a set of 4, the
task will be dequeued and enqueued sequentially without important
difference in comparison with initial state. The only difference is in
internal representation of plist queue of pushable tasks and the fact
that the task may won't be the first in a sequence of the same priority
tasks. But it seems to me it gives nothing.

Signed-off-by: Tkhai Kirill <tkhai@yandex.ru>
---
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 3640ebb..bf48343 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1774,43 +1774,36 @@ static void set_cpus_allowed_rt(struct task_struct *p,
 				const struct cpumask *new_mask)
 {
 	int weight = cpumask_weight(new_mask);
+	struct rq *rq;
 
 	BUG_ON(!rt_task(p));
 
 	/*
-	 * Update the migration status of the RQ if we have an RT task
-	 * which is running AND changing its weight value.
+	 * Just exit if it's not necessary to change migration status
 	 */
-	if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) {
-		struct rq *rq = task_rq(p);
-
-		if (!task_current(rq, p)) {
-			/*
-			 * Make sure we dequeue this task from the pushable list
-			 * before going further.  It will either remain off of
-			 * the list because we are no longer pushable, or it
-			 * will be requeued.
-			 */
-			if (p->rt.nr_cpus_allowed > 1)
-				dequeue_pushable_task(rq, p);
-
-			/*
-			 * Requeue if our weight is changing and still > 1
-			 */
-			if (weight > 1)
-				enqueue_pushable_task(rq, p);
+	if ((p->rt.nr_cpus_allowed > 1) == (weight > 1))
+		return;
 
-		}
+	if (!p->on_rq)
+		return;
 
-		if ((p->rt.nr_cpus_allowed <= 1) && (weight > 1)) {
-			rq->rt.rt_nr_migratory++;
-		} else if ((p->rt.nr_cpus_allowed > 1) && (weight <= 1)) {
-			BUG_ON(!rq->rt.rt_nr_migratory);
-			rq->rt.rt_nr_migratory--;
-		}
+	rq = task_rq(p);
 
-		update_rt_migration(&rq->rt);
+	/*
+	 * Several cpus were allowed but now it's not so OR vice versa
+	 */
+	if (weight <= 1) {
+		if (!task_current(rq, p))
+			dequeue_pushable_task(rq, p);
+		BUG_ON(!rq->rt.rt_nr_migratory);
+		rq->rt.rt_nr_migratory--;
+	} else {
+		if (!task_current(rq, p))
+			enqueue_pushable_task(rq, p);
+		rq->rt.rt_nr_migratory++;
 	}
+
+	update_rt_migration(&rq->rt);
 }
 
 /* Assumes rq->lock is held */





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

end of thread, other threads:[~2012-04-14 18:23 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-01 21:26 [PATCH]sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt() Kirill Tkhai
2011-12-20 17:44 ` Oleg Nesterov
2011-12-20 20:28   ` Tkhai Kirill
2011-12-20 21:09     ` Tkhai Kirill
2012-02-13 17:23 ` Steven Rostedt
2012-02-19 14:17   ` Kirill Tkhai
2012-03-16 23:58     ` Kirill Tkhai
2012-04-10 13:58       ` Steven Rostedt
2012-04-10 15:52     ` Steven Rostedt
2012-04-11  5:06       ` Kirill Tkhai
2012-04-14 18:22         ` [tip:sched/core] sched_rt: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt () tip-bot for Kirill Tkhai
2012-01-11 19:10 [PATCH] sched_rt.c: Avoid unnecessary dequeue and enqueue of pushable tasks in set_cpus_allowed_rt() Kirill Tkhai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).