Commit bcbd94f
dm crypt: fix a possible hang due to race condition on exit
A kernel thread executes __set_current_state(TASK_INTERRUPTIBLE),
__add_wait_queue, spin_unlock_irq and then tests kthread_should_stop().
It is possible that the processor reorders memory accesses so that
kthread_should_stop() is executed before __set_current_state(). If such
reordering happens, there is a possible race on thread termination:
CPU 0:
calls kthread_should_stop()
it tests KTHREAD_SHOULD_STOP bit, returns false
CPU 1:
calls kthread_stop(cc->write_thread)
sets the KTHREAD_SHOULD_STOP bit
calls wake_up_process on the kernel thread, that sets the thread
state to TASK_RUNNING
CPU 0:
sets __set_current_state(TASK_INTERRUPTIBLE)
spin_unlock_irq(&cc->write_thread_wait.lock)
schedule() - and the process is stuck and never terminates, because the
state is TASK_INTERRUPTIBLE and wake_up_process on CPU 1 already
terminated
Fix this race condition by using a new flag DM_CRYPT_EXIT_THREAD to
signal that the kernel thread should exit. The flag is set and tested
while holding cc->write_thread_wait.lock, so there is no possibility of
racy access to the flag.
Also, remove the unnecessary set_task_state(current, TASK_RUNNING)
following the schedule() call. When the process was woken up, its state
was already set to TASK_RUNNING. Other kernel code also doesn't set the
state to TASK_RUNNING following schedule() (for example,
do_wait_for_common in completion.c doesn't do it).
Fixes: dc26762 ("dm crypt: offload writes to thread")
Signed-off-by: Mikulas Patocka <[email protected]>
Cc: [email protected] # v4.0+
Signed-off-by: Mike Snitzer <[email protected]>1 parent 43e43c9 commit bcbd94f
1 file changed
+13
-9
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
112 | 112 | | |
113 | 113 | | |
114 | 114 | | |
115 | | - | |
| 115 | + | |
| 116 | + | |
116 | 117 | | |
117 | 118 | | |
118 | 119 | | |
| |||
1203 | 1204 | | |
1204 | 1205 | | |
1205 | 1206 | | |
| 1207 | + | |
| 1208 | + | |
| 1209 | + | |
| 1210 | + | |
| 1211 | + | |
1206 | 1212 | | |
1207 | 1213 | | |
1208 | 1214 | | |
1209 | 1215 | | |
1210 | 1216 | | |
1211 | | - | |
1212 | | - | |
1213 | | - | |
1214 | | - | |
1215 | | - | |
1216 | | - | |
1217 | 1217 | | |
1218 | 1218 | | |
1219 | | - | |
1220 | 1219 | | |
1221 | 1220 | | |
1222 | 1221 | | |
| |||
1531 | 1530 | | |
1532 | 1531 | | |
1533 | 1532 | | |
1534 | | - | |
| 1533 | + | |
| 1534 | + | |
| 1535 | + | |
| 1536 | + | |
| 1537 | + | |
1535 | 1538 | | |
| 1539 | + | |
1536 | 1540 | | |
1537 | 1541 | | |
1538 | 1542 | | |
| |||
0 commit comments