Skip to content

Commit 8a7730b

Browse files
Peter Zijlstrarostedt
authored andcommitted
sched: Simplify set_affinity_pending refcounts
commit 50caf9c upstream. Now that we have set_affinity_pending::stop_pending to indicate if a stopper is in progress, and we have the guarantee that if that stopper exists, it will (eventually) complete our @pending we can simplify the refcount scheme by no longer counting the stopper thread. 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 88a170e commit 8a7730b

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

kernel/sched/core.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,6 +1898,10 @@ struct migration_arg {
18981898
struct set_affinity_pending *pending;
18991899
};
19001900

1901+
/*
1902+
* @refs: number of wait_for_completion()
1903+
* @stop_pending: is @stop_work in use
1904+
*/
19011905
struct set_affinity_pending {
19021906
refcount_t refs;
19031907
unsigned int stop_pending;
@@ -2033,10 +2037,6 @@ static int migration_cpu_stop(void *data)
20332037
if (complete)
20342038
complete_all(&pending->done);
20352039

2036-
/* For pending->{arg,stop_work} */
2037-
if (pending && refcount_dec_and_test(&pending->refs))
2038-
wake_up_var(&pending->refs);
2039-
20402040
return 0;
20412041
}
20422042

@@ -2235,12 +2235,16 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag
22352235
push_task = get_task_struct(p);
22362236
}
22372237

2238+
/*
2239+
* If there are pending waiters, but no pending stop_work,
2240+
* then complete now.
2241+
*/
22382242
pending = p->migration_pending;
2239-
if (pending) {
2240-
refcount_inc(&pending->refs);
2243+
if (pending && !pending->stop_pending) {
22412244
p->migration_pending = NULL;
22422245
complete = true;
22432246
}
2247+
22442248
task_rq_unlock(rq, p, rf);
22452249

22462250
if (push_task) {
@@ -2249,7 +2253,7 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag
22492253
}
22502254

22512255
if (complete)
2252-
goto do_complete;
2256+
complete_all(&pending->done);
22532257

22542258
return 0;
22552259
}
@@ -2300,9 +2304,9 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag
23002304
if (!stop_pending)
23012305
pending->stop_pending = true;
23022306

2303-
refcount_inc(&pending->refs); /* pending->{arg,stop_work} */
23042307
if (flags & SCA_MIGRATE_ENABLE)
23052308
p->migration_flags &= ~MDF_PUSH;
2309+
23062310
task_rq_unlock(rq, p, rf);
23072311

23082312
if (!stop_pending) {
@@ -2318,27 +2322,31 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag
23182322
if (task_on_rq_queued(p))
23192323
rq = move_queued_task(rq, rf, p, dest_cpu);
23202324

2321-
p->migration_pending = NULL;
2322-
complete = true;
2325+
if (!pending->stop_pending) {
2326+
p->migration_pending = NULL;
2327+
complete = true;
2328+
}
23232329
}
23242330
task_rq_unlock(rq, p, rf);
23252331

2326-
do_complete:
23272332
if (complete)
23282333
complete_all(&pending->done);
23292334
}
23302335

23312336
wait_for_completion(&pending->done);
23322337

23332338
if (refcount_dec_and_test(&pending->refs))
2334-
wake_up_var(&pending->refs);
2339+
wake_up_var(&pending->refs); /* No UaF, just an address */
23352340

23362341
/*
23372342
* Block the original owner of &pending until all subsequent callers
23382343
* have seen the completion and decremented the refcount
23392344
*/
23402345
wait_var_event(&my_pending.refs, !refcount_read(&my_pending.refs));
23412346

2347+
/* ARGH */
2348+
WARN_ON_ONCE(my_pending.stop_pending);
2349+
23422350
return 0;
23432351
}
23442352

0 commit comments

Comments
 (0)