[PATCH 1/2] tcm_qla2xx: Add tcm_qla2xxx_free_wq for process context release

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

This patch adds a new tcm_qla2xxx_free_wq workqueue + qla_tgt_cmd->work_free
to provide process context when calling transport_generic_free_cmd() to release
individual qla_tgt_cmd->se_cmd descriptor memory.  This replaces the legacy
usage of tcm_qla2xxx_free_cmd() -> transport_generic_free_cmd_intr() that
released memory directly within transport_processing_thread() context.

Reported-by: Christoph Hellwig <hch@xxxxxx>
Cc: Christoph Hellwig <hch@xxxxxx>
Cc: Roland Dreier <roland@xxxxxxxxxxxxxxx>
Cc: Madhuranath Iyengar <mni@xxxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxxxxxxxx>
---
 drivers/scsi/qla2xxx/qla_target.h                 |    1 +
 drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c |   11 +++++++++++
 drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c   |   13 ++++++++++++-
 3 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 398de87..34ffe3c 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -928,6 +928,7 @@ struct qla_tgt_cmd {
 	struct completion cmd_free_comp;
 	struct completion cmd_stop_free_comp;
 	struct se_cmd se_cmd;
+	struct work_struct work_free;
 	/* Sense buffer that will be mapped into outgoing status */
 	unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER];
 
diff --git a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c
index 14d0f79..0a51acc 100644
--- a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c
+++ b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c
@@ -52,6 +52,8 @@
 struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs;
 struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs;
 
+struct workqueue_struct *tcm_qla2xxx_free_wq;
+
 static int tcm_qla2xxx_setup_nacl_from_rport(
 	struct se_portal_group *se_tpg,
 	struct se_node_acl *se_nacl,
@@ -1388,10 +1390,17 @@ static int tcm_qla2xxx_register_configfs(void)
 	tcm_qla2xxx_npiv_fabric_configfs = npiv_fabric;
 	pr_debug("TCM_QLA2XXX[0] - Set fabric -> tcm_qla2xxx_npiv_fabric_configfs\n");
 
+	tcm_qla2xxx_free_wq = alloc_workqueue("tcm_qla2xxx_free",
+						WQ_MEM_RECLAIM, 0);
+	if (!tcm_qla2xxx_free_wq)
+		goto out;
+
 	return 0;
 out:
 	if (tcm_qla2xxx_fabric_configfs != NULL)
 		target_fabric_configfs_deregister(tcm_qla2xxx_fabric_configfs);
+	if (tcm_qla2xxx_npiv_fabric_configfs != NULL)
+		target_fabric_configfs_deregister(tcm_qla2xxx_npiv_fabric_configfs);
 
 	return ret;
 }
@@ -1401,6 +1410,8 @@ static void tcm_qla2xxx_deregister_configfs(void)
 	if (!tcm_qla2xxx_fabric_configfs)
 		return;
 
+	destroy_workqueue(tcm_qla2xxx_free_wq);
+
 	target_fabric_configfs_deregister(tcm_qla2xxx_fabric_configfs);
 	tcm_qla2xxx_fabric_configfs = NULL;
 	pr_debug("TCM_QLA2XXX[0] - Cleared tcm_qla2xxx_fabric_configfs\n");
diff --git a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c
index cb97b68..1aa8ee4 100644
--- a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c
+++ b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c
@@ -52,6 +52,8 @@
 #include "tcm_qla2xxx_base.h"
 #include "tcm_qla2xxx_fabric.h"
 
+extern struct workqueue_struct *tcm_qla2xxx_free_wq;
+
 int tcm_qla2xxx_check_true(struct se_portal_group *se_tpg)
 {
 	return 1;
@@ -382,6 +384,14 @@ u32 tcm_qla2xxx_tpg_get_inst_index(struct se_portal_group *se_tpg)
 	return tpg->lport_tpgt;
 }
 
+static void tcm_qla2xxx_complete_free(struct work_struct *work)
+{
+	struct qla_tgt_cmd *cmd = container_of(work,
+				struct qla_tgt_cmd, work_free);
+
+	 transport_generic_free_cmd(&cmd->se_cmd, 0);
+}
+
 /*
  * Called from qla_target_template->free_cmd(), and will call
  * tcm_qla2xxx_release_cmd via normal struct target_core_fabric_ops
@@ -411,7 +421,8 @@ void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
 	atomic_set(&cmd->cmd_free, 1);
 	smp_mb__after_atomic_dec();
 
-	transport_generic_free_cmd_intr(&cmd->se_cmd);
+	INIT_WORK(&cmd->work_free, tcm_qla2xxx_complete_free);
+	queue_work(tcm_qla2xxx_free_wq, &cmd->work_free);
 }
 
 /*
-- 
1.7.2.5

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux