The module unload code will wait for a controller to be delete even when there is no controller and we wait for completion forever to happen. Thus only wait for the completion when there is a controller which needs to be removed. Reviewed-by: Hannes Reinecke <hare@xxxxxxx> Signed-off-by: Daniel Wagner <dwagner@xxxxxxx> --- drivers/nvme/host/fc.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 2ed75923507d..472ed285fd45 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -3932,10 +3932,11 @@ static int __init nvme_fc_init_module(void) return ret; } -static void +static bool nvme_fc_delete_controllers(struct nvme_fc_rport *rport) { struct nvme_fc_ctrl *ctrl; + bool cleanup = false; spin_lock(&rport->lock); list_for_each_entry(ctrl, &rport->ctrl_list, ctrl_list) { @@ -3943,21 +3944,28 @@ nvme_fc_delete_controllers(struct nvme_fc_rport *rport) "NVME-FC{%d}: transport unloading: deleting ctrl\n", ctrl->cnum); nvme_delete_ctrl(&ctrl->ctrl); + cleanup = true; } spin_unlock(&rport->lock); + + return cleanup; } -static void +static bool nvme_fc_cleanup_for_unload(void) { struct nvme_fc_lport *lport; struct nvme_fc_rport *rport; + bool cleanup = false; list_for_each_entry(lport, &nvme_fc_lport_list, port_list) { list_for_each_entry(rport, &lport->endp_list, endp_list) { - nvme_fc_delete_controllers(rport); + if (nvme_fc_delete_controllers(rport)) + cleanup = true; } } + + return cleanup; } static void __exit nvme_fc_exit_module(void) @@ -3967,10 +3975,8 @@ static void __exit nvme_fc_exit_module(void) spin_lock_irqsave(&nvme_fc_lock, flags); nvme_fc_waiting_to_unload = true; - if (!list_empty(&nvme_fc_lport_list)) { - need_cleanup = true; - nvme_fc_cleanup_for_unload(); - } + if (!list_empty(&nvme_fc_lport_list)) + need_cleanup = nvme_fc_cleanup_for_unload(); spin_unlock_irqrestore(&nvme_fc_lock, flags); if (need_cleanup) { pr_info("%s: waiting for ctlr deletes\n", __func__); -- 2.41.0