Skip to content

Commit 3f6cdb2

Browse files
Peter Zijlstrarostedt
authored andcommitted
sched: Simplify migration_cpu_stop()
commit c20cf06 upstream. When affine_move_task() issues a migration_cpu_stop(), the purpose of that function is to complete that @pending, not any random other p->migration_pending that might have gotten installed since. This realization much simplifies migration_cpu_stop() and allows further necessary steps to fix all this as it provides the guarantee that @pending's stopper will complete @pending (and not some random other @pending). Fixes: 6d337ea ("sched: Fix migrate_disable() vs set_cpus_allowed_ptr()") Cc: [email protected] Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Reviewed-by: Valentin Schneider <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Paul Gortmaker <[email protected]> Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent 6ecced9 commit 3f6cdb2

File tree

1 file changed

+8
-48
lines changed

1 file changed

+8
-48
lines changed

kernel/sched/core.c

Lines changed: 8 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1934,8 +1934,8 @@ static struct rq *__migrate_task(struct rq *rq, struct rq_flags *rf,
19341934
*/
19351935
static int migration_cpu_stop(void *data)
19361936
{
1937-
struct set_affinity_pending *pending;
19381937
struct migration_arg *arg = data;
1938+
struct set_affinity_pending *pending = arg->pending;
19391939
struct task_struct *p = arg->task;
19401940
int dest_cpu = arg->dest_cpu;
19411941
struct rq *rq = this_rq();
@@ -1957,25 +1957,6 @@ static int migration_cpu_stop(void *data)
19571957
raw_spin_lock(&p->pi_lock);
19581958
rq_lock(rq, &rf);
19591959

1960-
pending = p->migration_pending;
1961-
if (pending && !arg->pending) {
1962-
/*
1963-
* This happens from sched_exec() and migrate_task_to(),
1964-
* neither of them care about pending and just want a task to
1965-
* maybe move about.
1966-
*
1967-
* Even if there is a pending, we can ignore it, since
1968-
* affine_move_task() will have it's own stop_work's in flight
1969-
* which will manage the completion.
1970-
*
1971-
* Notably, pending doesn't need to match arg->pending. This can
1972-
* happen when tripple concurrent affine_move_task() first sets
1973-
* pending, then clears pending and eventually sets another
1974-
* pending.
1975-
*/
1976-
pending = NULL;
1977-
}
1978-
19791960
/*
19801961
* If task_rq(p) != rq, it cannot be migrated here, because we're
19811962
* holding rq->lock, if p->on_rq == 0 it cannot get enqueued because
@@ -1986,31 +1967,20 @@ static int migration_cpu_stop(void *data)
19861967
goto out;
19871968

19881969
if (pending) {
1989-
p->migration_pending = NULL;
1970+
if (p->migration_pending == pending)
1971+
p->migration_pending = NULL;
19901972
complete = true;
19911973
}
19921974

1993-
/* migrate_enable() -- we must not race against SCA */
1994-
if (dest_cpu < 0) {
1995-
/*
1996-
* When this was migrate_enable() but we no longer
1997-
* have a @pending, a concurrent SCA 'fixed' things
1998-
* and we should be valid again. Nothing to do.
1999-
*/
2000-
if (!pending) {
2001-
WARN_ON_ONCE(!cpumask_test_cpu(task_cpu(p), &p->cpus_mask));
2002-
goto out;
2003-
}
2004-
1975+
if (dest_cpu < 0)
20051976
dest_cpu = cpumask_any_distribute(&p->cpus_mask);
2006-
}
20071977

20081978
if (task_on_rq_queued(p))
20091979
rq = __migrate_task(rq, &rf, p, dest_cpu);
20101980
else
20111981
p->wake_cpu = dest_cpu;
20121982

2013-
} else if (dest_cpu < 0 || pending) {
1983+
} else if (pending) {
20141984
/*
20151985
* This happens when we get migrated between migrate_enable()'s
20161986
* preempt_enable() and scheduling the stopper task. At that
@@ -2025,22 +1995,13 @@ static int migration_cpu_stop(void *data)
20251995
* ->pi_lock, so the allowed mask is stable - if it got
20261996
* somewhere allowed, we're done.
20271997
*/
2028-
if (pending && cpumask_test_cpu(task_cpu(p), p->cpus_ptr)) {
2029-
p->migration_pending = NULL;
1998+
if (cpumask_test_cpu(task_cpu(p), p->cpus_ptr)) {
1999+
if (p->migration_pending == pending)
2000+
p->migration_pending = NULL;
20302001
complete = true;
20312002
goto out;
20322003
}
20332004

2034-
/*
2035-
* When this was migrate_enable() but we no longer have an
2036-
* @pending, a concurrent SCA 'fixed' things and we should be
2037-
* valid again. Nothing to do.
2038-
*/
2039-
if (!pending) {
2040-
WARN_ON_ONCE(!cpumask_test_cpu(task_cpu(p), &p->cpus_mask));
2041-
goto out;
2042-
}
2043-
20442005
/*
20452006
* When migrate_enable() hits a rq mis-match we can't reliably
20462007
* determine is_migration_disabled() and so have to chase after
@@ -2058,7 +2019,6 @@ static int migration_cpu_stop(void *data)
20582019
complete_all(&pending->done);
20592020

20602021
/* For pending->{arg,stop_work} */
2061-
pending = arg->pending;
20622022
if (pending && refcount_dec_and_test(&pending->refs))
20632023
wake_up_var(&pending->refs);
20642024

0 commit comments

Comments
 (0)