diff mbox series

[08/12] qla2xxx: Add workqueue to delete fcport from bsg sp->free().

Message ID 20190212234046.29809-9-hmadhani@marvell.com (mailing list archive)
State Superseded
Headers show
Series qla2xxx: Misc bug fixes for the driver | expand

Commit Message

Himanshu Madhani Feb. 12, 2019, 11:40 p.m. UTC
From: Joe Carnuccio <joe.carnuccio@cavium.com>

This patch adds workqueue mechanism for deleting fcport
via BSG interface.

Signed-off-by: Joe Carnuccio <joe.carnuccio@cavium.com>
Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
---
 drivers/scsi/qla2xxx/qla_bsg.c | 18 +++++++++++++++++-
 drivers/scsi/qla2xxx/qla_def.h |  1 +
 drivers/scsi/qla2xxx/qla_os.c  | 11 +++++++++++
 3 files changed, 29 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 4a9fd8d944d6..d9b6af975691 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -11,6 +11,14 @@ 
 #include <linux/delay.h>
 #include <linux/bsg-lib.h>
 
+static void qla2xxx_free_fcport_work(struct work_struct *work)
+{
+	struct fc_port *fcport = container_of(work, typeof(*fcport),
+	    free_work);
+
+	qla2x00_free_fcport(fcport);
+}
+
 /* BSG support for ELS/CT pass through */
 void
 qla2x00_bsg_job_done(void *ptr, int res)
@@ -57,8 +65,16 @@  qla2x00_bsg_sp_free(void *ptr)
 
 	if (sp->type == SRB_CT_CMD ||
 	    sp->type == SRB_FXIOCB_BCMD ||
-	    sp->type == SRB_ELS_CMD_HST)
+	    sp->type == SRB_ELS_CMD_HST) {
+		if (ha->free_fcport) {
+			INIT_WORK(&sp->fcport->free_work,
+			    qla2xxx_free_fcport_work);
+			queue_work(ha->free_fcport, &sp->fcport->free_work);
+			goto done;
+		}
 		kfree(sp->fcport);
+	}
+done:
 	qla2x00_rel_sp(sp);
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index c0f7593666a1..a0304746e8a5 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -4190,6 +4190,7 @@  struct qla_hw_data {
 	struct work_struct idc_state_handler;
 	struct work_struct nic_core_unrecoverable;
 	struct work_struct board_disable;
+	struct workqueue_struct *free_fcport;
 
 	struct mr_data_fx00 mr;
 	uint32_t chip_reset;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 7bf23943c815..8bc60ba7fd13 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3196,6 +3196,12 @@  qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	    host->max_cmd_len, host->max_channel, host->max_lun,
 	    host->transportt, sht->vendor_id);
 
+	ha->free_fcport = create_workqueue("free_fcport");
+	if (!ha->free_fcport) {
+		ql_log(ql_log_info, base_vha, 0xee00,
+		    "Failed to allocate workqueue ha->free_fcport\n");
+	}
+
 	INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn);
 
 	/* Set up the irqs */
@@ -3650,6 +3656,11 @@  qla2x00_destroy_deferred_work(struct qla_hw_data *ha)
 		ha->dpc_hp_wq = NULL;
 	}
 
+	if (ha->free_fcport) {
+		destroy_workqueue(ha->free_fcport);
+		ha->free_fcport = NULL;
+	}
+
 	/* Kill the kernel thread for this host */
 	if (ha->dpc_thread) {
 		struct task_struct *t = ha->dpc_thread;