All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
To: skashyap@marvell.com, jhasan@marvell.com,
	GR-QLogic-Storage-Upstream@marvell.com, jejb@linux.ibm.com,
	martin.petersen@oracle.com, linux@armlinux.org.uk
Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org,
	netdev@vger.kernel.org, Jiasheng Jiang <jiasheng@iscas.ac.cn>
Subject: [PATCH] scsi: qedf: Add missing checks for create_workqueue
Date: Wed,  8 Feb 2023 10:06:46 +0800	[thread overview]
Message-ID: <20230208020646.36294-1-jiasheng@iscas.ac.cn> (raw)

Add the checks for the return value of the create_workqueue in order to
avoid NULL pointer dereference.
Moreover, the allocated "qedf->link_update_wq" should be destroyed when
__qedf_probe fails later in order to avoid memory leak.

Fixes: 61d8658b4a43 ("scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.")
Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
---
 drivers/scsi/qedf/qedf_main.c | 56 ++++++++++++++++++++++-------------
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
index 35e16600fc63..ff90291530a7 100644
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -3360,6 +3360,11 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 	sprintf(host_buf, "qedf_%u_link",
 	    qedf->lport->host->host_no);
 	qedf->link_update_wq = create_workqueue(host_buf);
+	if (!qedf->link_update_wq) {
+		QEDF_ERR(&(qedf->dbg_ctx), "Failed to link workqueue.\n");
+		rc = -ENOMEM;
+		goto err1;
+	}
 	INIT_DELAYED_WORK(&qedf->link_update, qedf_handle_link_update);
 	INIT_DELAYED_WORK(&qedf->link_recovery, qedf_link_recovery);
 	INIT_DELAYED_WORK(&qedf->grcdump_work, qedf_wq_grcdump);
@@ -3394,14 +3399,14 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 		}
 		QEDF_ERR(&qedf->dbg_ctx, "common probe failed.\n");
 		rc = -ENODEV;
-		goto err1;
+		goto err2;
 	}
 
 	/* Learn information crucial for qedf to progress */
 	rc = qed_ops->fill_dev_info(qedf->cdev, &qedf->dev_info);
 	if (rc) {
 		QEDF_ERR(&(qedf->dbg_ctx), "Failed to dev info.\n");
-		goto err1;
+		goto err2;
 	}
 
 	QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
@@ -3420,7 +3425,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 	rc = qedf_set_fcoe_pf_param(qedf);
 	if (rc) {
 		QEDF_ERR(&(qedf->dbg_ctx), "Cannot set fcoe pf param.\n");
-		goto err2;
+		goto err3;
 	}
 	qed_ops->common->update_pf_params(qedf->cdev, &qedf->pf_params);
 
@@ -3428,7 +3433,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 	rc = qed_ops->fill_dev_info(qedf->cdev, &qedf->dev_info);
 	if (rc) {
 		QEDF_ERR(&qedf->dbg_ctx, "Failed to fill dev info.\n");
-		goto err2;
+		goto err3;
 	}
 
 	if (mode != QEDF_MODE_RECOVERY) {
@@ -3437,7 +3442,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 			QEDF_ERR(&qedf->dbg_ctx, "Cannot register devlink\n");
 			rc = PTR_ERR(qedf->devlink);
 			qedf->devlink = NULL;
-			goto err2;
+			goto err3;
 		}
 	}
 
@@ -3454,7 +3459,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 	if (rc) {
 
 		QEDF_ERR(&(qedf->dbg_ctx), "Cannot start slowpath.\n");
-		goto err2;
+		goto err3;
 	}
 
 	/* Start the Slowpath-process */
@@ -3467,7 +3472,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 	rc = qed_ops->common->slowpath_start(qedf->cdev, &slowpath_params);
 	if (rc) {
 		QEDF_ERR(&(qedf->dbg_ctx), "Cannot start slowpath.\n");
-		goto err2;
+		goto err3;
 	}
 
 	/*
@@ -3480,13 +3485,13 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 	rc = qedf_setup_int(qedf);
 	if (rc) {
 		QEDF_ERR(&qedf->dbg_ctx, "Setup interrupts failed.\n");
-		goto err3;
+		goto err4;
 	}
 
 	rc = qed_ops->start(qedf->cdev, &qedf->tasks);
 	if (rc) {
 		QEDF_ERR(&(qedf->dbg_ctx), "Cannot start FCoE function.\n");
-		goto err4;
+		goto err5;
 	}
 	task_start = qedf_get_task_mem(&qedf->tasks, 0);
 	task_end = qedf_get_task_mem(&qedf->tasks, MAX_TID_BLOCKS_FCOE - 1);
@@ -3546,7 +3551,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 	if (!qedf->cmd_mgr) {
 		QEDF_ERR(&(qedf->dbg_ctx), "Failed to allocate cmd mgr.\n");
 		rc = -ENOMEM;
-		goto err5;
+		goto err6;
 	}
 
 	if (mode != QEDF_MODE_RECOVERY) {
@@ -3559,7 +3564,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 		if (rc) {
 			QEDF_WARN(&qedf->dbg_ctx,
 				  "Error adding Scsi_Host rc=0x%x.\n", rc);
-			goto err6;
+			goto err7;
 		}
 	}
 
@@ -3574,7 +3579,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 	if (!qedf->ll2_recv_wq) {
 		QEDF_ERR(&(qedf->dbg_ctx), "Failed to LL2 workqueue.\n");
 		rc = -ENOMEM;
-		goto err7;
+		goto err8;
 	}
 
 #ifdef CONFIG_DEBUG_FS
@@ -3587,7 +3592,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 	rc = qed_ops->ll2->start(qedf->cdev, &params);
 	if (rc) {
 		QEDF_ERR(&(qedf->dbg_ctx), "Could not start Light L2.\n");
-		goto err7;
+		goto err8;
 	}
 	set_bit(QEDF_LL2_STARTED, &qedf->flags);
 
@@ -3607,7 +3612,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 		if (rc) {
 			QEDF_ERR(&(qedf->dbg_ctx),
 			    "qedf_lport_setup failed.\n");
-			goto err7;
+			goto err8;
 		}
 	}
 
@@ -3618,7 +3623,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 		QEDF_ERR(&(qedf->dbg_ctx), "Failed to start timer "
 			  "workqueue.\n");
 		rc = -ENOMEM;
-		goto err7;
+		goto err8;
 	}
 
 	/* DPC workqueue is not reaped during recovery unload */
@@ -3626,6 +3631,11 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 		sprintf(host_buf, "qedf_%u_dpc",
 		    qedf->lport->host->host_no);
 		qedf->dpc_wq = create_workqueue(host_buf);
+		if (!qedf->dpc_wq) {
+			QEDF_ERR(&(qedf->dbg_ctx), "Failed to dpc workqueue.\n");
+			rc = -ENOMEM;
+			goto err9;
+		}
 	}
 	INIT_DELAYED_WORK(&qedf->recovery_work, qedf_recovery_handler);
 
@@ -3682,7 +3692,9 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 	/* All good */
 	return 0;
 
-err7:
+err9:
+	destroy_workqueue(qedf->timer_work_queue);
+err8:
 	if (qedf->ll2_recv_wq)
 		destroy_workqueue(qedf->ll2_recv_wq);
 	fc_remove_host(qedf->lport->host);
@@ -3690,17 +3702,19 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
 #ifdef CONFIG_DEBUG_FS
 	qedf_dbg_host_exit(&(qedf->dbg_ctx));
 #endif
-err6:
+err7:
 	qedf_cmd_mgr_free(qedf->cmd_mgr);
-err5:
+err6:
 	qed_ops->stop(qedf->cdev);
-err4:
+err5:
 	qedf_free_fcoe_pf_param(qedf);
 	qedf_sync_free_irqs(qedf);
-err3:
+err4:
 	qed_ops->common->slowpath_stop(qedf->cdev);
-err2:
+err3:
 	qed_ops->common->remove(qedf->cdev);
+err2:
+	destroy_workqueue(qedf->link_update_wq);
 err1:
 	scsi_host_put(lport->host);
 err0:
-- 
2.25.1


                 reply	other threads:[~2023-02-08  2:07 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230208020646.36294-1-jiasheng@iscas.ac.cn \
    --to=jiasheng@iscas.ac.cn \
    --cc=GR-QLogic-Storage-Upstream@marvell.com \
    --cc=jejb@linux.ibm.com \
    --cc=jhasan@marvell.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=martin.petersen@oracle.com \
    --cc=netdev@vger.kernel.org \
    --cc=skashyap@marvell.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.