Flushing system-wide workqueues is dangerous and will be forbidden. Since system_long_wq is used only inside rnbd_destroy_sessions(), let's use list_head than creating a local workqueue for tracking work_struct to flush. Link: https://lkml.kernel.org/r/49925af7-78a8-a3dd-bce6-cfc02e1a9236@xxxxxxxxxxxxxxxxxxx Signed-off-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx> --- Notice: This patch is only compile tested. Please test before applying. drivers/block/rnbd/rnbd-clt.c | 5 ++++- drivers/block/rnbd/rnbd-clt.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c index b66e8840b94b..b14e7c15133e 100644 --- a/drivers/block/rnbd/rnbd-clt.c +++ b/drivers/block/rnbd/rnbd-clt.c @@ -1730,6 +1730,7 @@ static void rnbd_destroy_sessions(void) { struct rnbd_clt_session *sess, *sn; struct rnbd_clt_dev *dev, *tn; + LIST_HEAD(list); /* Firstly forbid access through sysfs interface */ rnbd_clt_destroy_sysfs_files(); @@ -1762,11 +1763,13 @@ static void rnbd_destroy_sessions(void) */ INIT_WORK(&dev->unmap_on_rmmod_work, unmap_device_work); queue_work(system_long_wq, &dev->unmap_on_rmmod_work); + list_add_tail(&dev->unmap_on_rmmod_list, &list); } rnbd_clt_put_sess(sess); } /* Wait for all scheduled unmap works */ - flush_workqueue(system_long_wq); + list_for_each_entry(dev, &list, unmap_on_rmmod_list) + flush_work(&dev->unmap_on_rmmod_work); WARN_ON(!list_empty(&sess_list)); } diff --git a/drivers/block/rnbd/rnbd-clt.h b/drivers/block/rnbd/rnbd-clt.h index 2e2e8c4a85c1..a6d704abda61 100644 --- a/drivers/block/rnbd/rnbd-clt.h +++ b/drivers/block/rnbd/rnbd-clt.h @@ -136,6 +136,7 @@ struct rnbd_clt_dev { char *blk_symlink_name; refcount_t refcount; struct work_struct unmap_on_rmmod_work; + struct list_head unmap_on_rmmod_list; }; /* rnbd-clt.c */ -- 2.32.0