summaryrefslogtreecommitdiff
path: root/drivers/block/drbd/drbd_worker.c
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2011-05-02 11:47:18 +0200
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 16:53:00 +0100
commit992d6e91d3654c11c2e4d8d5933ffbf82a0440f0 (patch)
treeb97d1371d9a0a93d539174ecdd8cfe205b56cf43 /drivers/block/drbd/drbd_worker.c
parentf3dfa40a67c354a5886c5ae53a9c5d3a2c6fd06e (diff)
drbd: fix thread stop deadlock
There are races where the receiver may be exiting, but still need the worker to process some stuff. Do not wait for the receiver to die from an exiting worker. The receiver must already be dead in case the worker decides to exit. If the receiver was still alive, it may still want to queue work, and do drbd_flush_workqueue() from it's disconnect cleanup code, which would no longer be processed by an exiting worker. This also would deadlock, if the worker was to synchornously wait for the receiver to die. Do not implicitly stop the worker. The worker will only be stopped from configuration context, from conn_reconfig_done(), drbd_adm_down() or drbd_adm_delete_connection(), after making sure the receiver is already stopped. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_worker.c')
-rw-r--r--drivers/block/drbd/drbd_worker.c4
1 files changed, 0 insertions, 4 deletions
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 7a73bd4287c4..0da1547bb2d2 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1744,10 +1744,6 @@ int drbd_worker(struct drbd_thread *thi)
*/
spin_unlock_irq(&tconn->data.work.q_lock);
- /* _drbd_set_state only uses stop_nowait.
- * wait here for the exiting receiver. */
- drbd_thread_stop(&tconn->receiver);
-
down_read(&drbd_cfg_rwsem);
idr_for_each_entry(&tconn->volumes, mdev, vnr) {
D_ASSERT(mdev->state.disk == D_DISKLESS && mdev->state.conn == C_STANDALONE);