forked fromtorvalds/linux
- Notifications
You must be signed in to change notification settings - Fork0
Commitf97bb52
Peter Zijlstra
sched: Fix data-race in wakeup
Mel reported that on some ARM64 platforms loadavg goes bananas andWill tracked it down to the following race: CPU0CPU1 schedule() prev->sched_contributes_to_load = X; deactivate_task(prev);try_to_wake_up() if (p->on_rq &&) // false if (smp_load_acquire(&p->on_cpu) && // true ttwu_queue_wakelist()) p->sched_remote_wakeup = Y; smp_store_release(prev->on_cpu, 0);where both p->sched_contributes_to_load and p->sched_remote_wakeup arein the same word, and thus the stores X and Y race (and can clobberone another's data).Whereas prior to commitc6e7bd7 ("sched/core: Optimize ttwu()spinning on p->on_cpu") the p->on_cpu handoff serialized access top->sched_remote_wakeup (just as it still does withp->sched_contributes_to_load) that commit broke that by callingttwu_queue_wakelist() with p->on_cpu != 0.However, due to p->XXX = Xttwu() schedule() if (p->on_rq && ...) // false smp_mb__after_spinlock() if (smp_load_acquire(&p->on_cpu) && deactivate_task() ttwu_queue_wakelist()) p->on_rq = 0; p->sched_remote_wakeup = Y;We can be sure any 'current' store is complete and 'current' isguaranteed asleep. Therefore we can move p->sched_remote_wakeup intothe current flags word.Note: while the observed failure was loadavg accounting gone wrong dueto ttwu() cobbering p->sched_contributes_to_load, the reverse problemis also possible where schedule() clobbers p->sched_remote_wakeup,this could result in enqueue_entity() wrecking ->vruntime and causingscheduling artifacts.Fixes:c6e7bd7 ("sched/core: Optimize ttwu() spinning on p->on_cpu")Reported-by: Mel Gorman <mgorman@techsingularity.net>Debugged-by: Will Deacon <will@kernel.org>Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>Link:https://lkml.kernel.org/r/20201117083016.GK3121392@hirez.programming.kicks-ass.net1 parent8e1ac42 commitf97bb52
1 file changed
+15
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
769 | 769 | | |
770 | 770 | | |
771 | 771 | | |
772 | | - | |
773 | 772 | | |
774 | 773 | | |
775 | 774 | | |
| |||
779 | 778 | | |
780 | 779 | | |
781 | 780 | | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
782 | 796 | | |
783 | 797 | | |
784 | 798 | | |
| |||
0 commit comments
Comments
(0)