To avoid complex lock ordering issues always delete loop devices outside of loop_ctl_mutex. In loop_control_remove the Lo_deleting state can be used to prevent further lookups, and given that module unload is synchronized vs new opens of the control device and thus ioctls there is no need for locks there at all. Based on patches from Hillf Danton <hdanton@xxxxxxxx> and Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx>. Reported-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx> Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- drivers/block/loop.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index e93baff664c9..043673bda8b3 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -2480,7 +2480,11 @@ static int loop_control_remove(int idx) mutex_unlock(&lo->lo_mutex); idr_remove(&loop_index_idr, lo->lo_number); + mutex_unlock(&loop_ctl_mutex); + loop_remove(lo); + return 0; + out_unlock_ctrl: mutex_unlock(&loop_ctl_mutex); return ret; @@ -2611,11 +2615,12 @@ static void __exit loop_exit(void) unregister_blkdev(LOOP_MAJOR, "loop"); misc_deregister(&loop_misc); - mutex_lock(&loop_ctl_mutex); + /* + * No need for loop_ctl_mutex given that no new ioctls and thus + * additions and removals can happen in parallel to module unloading. + */ idr_for_each_entry(&loop_index_idr, lo, id) loop_remove(lo); - mutex_unlock(&loop_ctl_mutex); - idr_destroy(&loop_index_idr); } -- 2.30.2