Remove broken task->state references and let wake_up_process() DTRT. The anti-pattern in these patches breaks the ordering of ->state vs COND as described in the comment near set_current_state() and can lead to missed wakeups: (OoO load, observes RUNNING)<-. for (;;) { | t->state = UNINTERRUPTIBLE; | smp_mb(); ,-----> | (observes !COND) | / if (COND) ---------' | COND = 1; break; `- if (t->state != RUNNING) wake_up_process(t); // not done schedule(); // forever waiting } t->state = TASK_RUNNING;
Showing the changes to kernel (1 of 4 files). Show all
Unified · Split
| @@ -76,7 +76,7 @@ static void wakeup_softirqd(void) · 75 unmodified lines | |||
| 76 | /* Interrupts are disabled: no need to stop preemption */ | 76 | /* Interrupts are disabled: no need to stop preemption */ |
| 77 | struct task_struct *tsk = __this_cpu_read(ksoftirqd); | 77 | struct task_struct *tsk = __this_cpu_read(ksoftirqd); |
| 78 | 78 | ||
| 79 | if (tsk && tsk->state != TASK_RUNNING) | 79 | if (tsk) |
| 80 | wake_up_process(tsk); | 80 | wake_up_process(tsk); |
| 81 | } | 81 | } |
| 82 | 82 | ||