aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched/core.c
diff options
context:
space:
mode:
authorKirill Tkhai <ktkhai@parallels.com>2014-08-20 05:47:50 -0400
committerIngo Molnar <mingo@kernel.org>2014-08-20 08:53:02 -0400
commita1e01829796aa7a993e28ffd7fee5c8d525be175 (patch)
tree9ae2970e5c0dc25972bf3d7663d997ab8808ddad /kernel/sched/core.c
parentcca26e8009d1939a6a5bf0200d276fa26f03e536 (diff)
sched: Remove double_rq_lock() from __migrate_task()
Avoid double_rq_lock() and use TASK_ON_RQ_MIGRATING for __migrate_task(). The advantage is (obviously) not holding two rq->lock's at the same time and thereby increasing parallelism. The important point to note is that because we acquire dst->lock immediately after releasing src->lock the potential wait time of task_rq_lock() callers on TASK_ON_RQ_MIGRATING is not longer than it would have been in the double rq lock scenario. Signed-off-by: Kirill Tkhai <ktkhai@parallels.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Paul Turner <pjt@google.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Mike Galbraith <umgwanakikbuti@gmail.com> Cc: Kirill Tkhai <tkhai@yandex.ru> Cc: Tim Chen <tim.c.chen@linux.intel.com> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Link: http://lkml.kernel.org/r/1408528070.23412.89.camel@tkhai Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r--kernel/sched/core.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 71b836034912..a773c919d88d 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4679,20 +4679,20 @@ EXPORT_SYMBOL_GPL(set_cpus_allowed_ptr);
4679 */ 4679 */
4680static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) 4680static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
4681{ 4681{
4682 struct rq *rq_dest, *rq_src; 4682 struct rq *rq;
4683 int ret = 0; 4683 int ret = 0;
4684 4684
4685 if (unlikely(!cpu_active(dest_cpu))) 4685 if (unlikely(!cpu_active(dest_cpu)))
4686 return ret; 4686 return ret;
4687 4687
4688 rq_src = cpu_rq(src_cpu); 4688 rq = cpu_rq(src_cpu);
4689 rq_dest = cpu_rq(dest_cpu);
4690 4689
4691 raw_spin_lock(&p->pi_lock); 4690 raw_spin_lock(&p->pi_lock);
4692 double_rq_lock(rq_src, rq_dest); 4691 raw_spin_lock(&rq->lock);
4693 /* Already moved. */ 4692 /* Already moved. */
4694 if (task_cpu(p) != src_cpu) 4693 if (task_cpu(p) != src_cpu)
4695 goto done; 4694 goto done;
4695
4696 /* Affinity changed (again). */ 4696 /* Affinity changed (again). */
4697 if (!cpumask_test_cpu(dest_cpu, tsk_cpus_allowed(p))) 4697 if (!cpumask_test_cpu(dest_cpu, tsk_cpus_allowed(p)))
4698 goto fail; 4698 goto fail;
@@ -4702,15 +4702,22 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
4702 * placed properly. 4702 * placed properly.
4703 */ 4703 */
4704 if (task_on_rq_queued(p)) { 4704 if (task_on_rq_queued(p)) {
4705 dequeue_task(rq_src, p, 0); 4705 dequeue_task(rq, p, 0);
4706 p->on_rq = TASK_ON_RQ_MIGRATING;
4706 set_task_cpu(p, dest_cpu); 4707 set_task_cpu(p, dest_cpu);
4707 enqueue_task(rq_dest, p, 0); 4708 raw_spin_unlock(&rq->lock);
4708 check_preempt_curr(rq_dest, p, 0); 4709
4710 rq = cpu_rq(dest_cpu);
4711 raw_spin_lock(&rq->lock);
4712 BUG_ON(task_rq(p) != rq);
4713 p->on_rq = TASK_ON_RQ_QUEUED;
4714 enqueue_task(rq, p, 0);
4715 check_preempt_curr(rq, p, 0);
4709 } 4716 }
4710done: 4717done:
4711 ret = 1; 4718 ret = 1;
4712fail: 4719fail:
4713 double_rq_unlock(rq_src, rq_dest); 4720 raw_spin_unlock(&rq->lock);
4714 raw_spin_unlock(&p->pi_lock); 4721 raw_spin_unlock(&p->pi_lock);
4715 return ret; 4722 return ret;
4716} 4723}