The 'qla_tgt_wq' workqueue is used for generic command aborts,
not just target-related functions. So allocate the workqueue
always to avoid a kernel crash when aborting commands.

Signed-off-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 582d1663f971..e35b84d9c1c1 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -7419,6 +7419,13 @@ int __init qlt_init(void)
                return -EINVAL;
        }
 
+       qla_tgt_wq = alloc_workqueue("qla_tgt_wq", 0, 0);
+       if (!qla_tgt_wq) {
+               ql_log(ql_log_fatal, NULL, 0xe06f,
+                   "alloc_workqueue for qla_tgt_wq failed\n");
+               return -ENOMEM;
+       }
+
        if (!QLA_TGT_MODE_ENABLED())
                return 0;
 
@@ -7428,7 +7435,8 @@ int __init qlt_init(void)
        if (!qla_tgt_mgmt_cmd_cachep) {
                ql_log(ql_log_fatal, NULL, 0xd04b,
                    "kmem_cache_create for qla_tgt_mgmt_cmd_cachep failed\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto out_workqueue;
        }
 
        qla_tgt_plogi_cachep = kmem_cache_create("qla_tgt_plogi_cachep",
@@ -7451,33 +7459,27 @@ int __init qlt_init(void)
                goto out_plogi_cachep;
        }
 
-       qla_tgt_wq = alloc_workqueue("qla_tgt_wq", 0, 0);
-       if (!qla_tgt_wq) {
-               ql_log(ql_log_fatal, NULL, 0xe06f,
-                   "alloc_workqueue for qla_tgt_wq failed\n");
-               ret = -ENOMEM;
-               goto out_cmd_mempool;
-       }
        /*
         * Return 1 to signal that initiator-mode is being disabled
         */
        return (ql2x_ini_mode == QLA2XXX_INI_MODE_DISABLED) ? 1 : 0;
 
-out_cmd_mempool:
-       mempool_destroy(qla_tgt_mgmt_cmd_mempool);
 out_plogi_cachep:
        kmem_cache_destroy(qla_tgt_plogi_cachep);
 out_mgmt_cmd_cachep:
        kmem_cache_destroy(qla_tgt_mgmt_cmd_cachep);
+out_workqueue:
+       destroy_workqueue(qla_tgt_wq);
        return ret;
 }
 
 void qlt_exit(void)
 {
+       destroy_workqueue(qla_tgt_wq);
+
        if (!QLA_TGT_MODE_ENABLED())
                return;
 
-       destroy_workqueue(qla_tgt_wq);
        mempool_destroy(qla_tgt_mgmt_cmd_mempool);
        kmem_cache_destroy(qla_tgt_plogi_cachep);
        kmem_cache_destroy(qla_tgt_mgmt_cmd_cachep);
-- 
2.16.4

Reply via email to