Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull scheduler fix from Thomas Gleixner:
"Fix a long standing state race in finish_task_switch()"

* 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
sched/core: Fix TASK_DEAD race in finish_task_switch()

+8 -7
+5 -5
kernel/sched/core.c
··· 2517 2517 * If a task dies, then it sets TASK_DEAD in tsk->state and calls 2518 2518 * schedule one last time. The schedule call will never return, and 2519 2519 * the scheduled task must drop that reference. 2520 - * The test for TASK_DEAD must occur while the runqueue locks are 2521 - * still held, otherwise prev could be scheduled on another cpu, die 2522 - * there before we look at prev->state, and then the reference would 2523 - * be dropped twice. 2524 - * Manfred Spraul <manfred@colorfullife.com> 2520 + * 2521 + * We must observe prev->state before clearing prev->on_cpu (in 2522 + * finish_lock_switch), otherwise a concurrent wakeup can get prev 2523 + * running on another CPU and we could rave with its RUNNING -> DEAD 2524 + * transition, resulting in a double drop. 2525 2525 */ 2526 2526 prev_state = prev->state; 2527 2527 vtime_task_switch(prev);
+3 -2
kernel/sched/sched.h
··· 1078 1078 * After ->on_cpu is cleared, the task can be moved to a different CPU. 1079 1079 * We must ensure this doesn't happen until the switch is completely 1080 1080 * finished. 1081 + * 1082 + * Pairs with the control dependency and rmb in try_to_wake_up(). 1081 1083 */ 1082 - smp_wmb(); 1083 - prev->on_cpu = 0; 1084 + smp_store_release(&prev->on_cpu, 0); 1084 1085 #endif 1085 1086 #ifdef CONFIG_DEBUG_SPINLOCK 1086 1087 /* this is a valid case when another task releases the spinlock */