[PATCH 2/3] qla2xxx/tcm_qla2xxx: Convert to use generic active I/O shutdown logic

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

 



From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

This patch converts qla2xxx/tcm_qla2xxx to use the new generic active
I/O shutdown logic.  This includes the conversion and removal of existing
internal active I/O shutdown code for qla_tgt_sess->sess_cmd_list with
the following changes:

*) Convert tcm_qla2xxx_handle_cmd() to use target_get_sess_cmd() for
   incoming I/O processing
*) Refactoring of tcm_qla2xxx_release_cmd() into tcm_qla2xxx_check_release_cmd()
   for TFO->check_release_cmd()
*) Make tcm_qla2xxx_check_release_cmd() to use target_put_sess_cmd() to
   check for active I/O completion.
*) Add target_splice_sess_cmd_list() and target_wait_for_sess_cmds()
   callers into tcm_qla2xxx_free_session() to wait for outstanding
   I/O to complete during session shutdown.
*) Removal of qla_tgt_wait_for_cmds() and associated qla_tgt_cmd and
   qla_tgt_sess members
*) Removal of tcm_qla2xxx_release_shutdown_check()

Cc: Christoph Hellwig <hch@xxxxxx>
Cc: Roland Dreier <roland@xxxxxxxxxxxxxxx>
Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
---
 drivers/scsi/qla2xxx/qla_target.c                 |   59 ------------------
 drivers/scsi/qla2xxx/qla_target.h                 |    4 -
 drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c |   10 +++
 drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c   |   67 +++++++--------------
 drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h   |    1 +
 5 files changed, 34 insertions(+), 107 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 0cfd448..121db91 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -369,61 +369,6 @@ void qla_tgt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
 
 }
 
-/*
- * Called with qla_hw_data->hardware_lock held.
- */
-static void qla_tgt_wait_for_cmds(struct qla_tgt_sess *sess, struct qla_hw_data *ha)
-{
-	LIST_HEAD(tmp_list);
-	struct qla_tgt_cmd *cmd;
-	struct se_cmd *se_cmd;
-
-	list_splice_init(&sess->sess_cmd_list, &tmp_list);
-
-	while (!list_empty(&tmp_list)) {
-
-		cmd = list_entry(tmp_list.next, struct qla_tgt_cmd, cmd_list);
-		ql_dbg(ql_dbg_tgt_mgt, sess->vha, 0xe100, "Waiting for cmd:"
-			" %p\n", cmd);
-		/*
-		 * This will signal that completion should be called from
-		 * tcm_qla2xxx_release_cmd() context.
-		 */ 
-		atomic_set(&cmd->cmd_free_comp_set, 1);
-		spin_unlock_irq(&ha->hardware_lock);
-
-		list_del(&cmd->cmd_list);
-
-		se_cmd = &cmd->se_cmd;
-		/*
-		 * Wait for completion of the outstanding descriptor in
-		 * tcm_qla2xxx_release_cmd() from transport processing
-		 * context, then a direct call to qla_tgt_free_cmd() below.
-		 */
-		ql_dbg(ql_dbg_tgt_mgt, sess->vha, 0xe101, "Before"
-			" wait_for_completion(&cmd->cmd_free_comp); cmd: %p,"
-			" se_cmd: %p\n", cmd, se_cmd);
-
-		wait_for_completion(&cmd->cmd_free_comp);
-
-		ql_dbg(ql_dbg_tgt_mgt, sess->vha, 0xe102, "After"
-			" wait_for_completion(&cmd->cmd_free_comp); cmd: %p,"
-			" se_cmd: %p\n", cmd, se_cmd);
-
-		atomic_set(&cmd->cmd_free, 0);
-		smp_mb__after_atomic_dec();
-
-		qla_tgt_free_cmd(cmd);
-
-		ql_dbg(ql_dbg_tgt_mgt, sess->vha, 0xe103, "After"
-			" qla_tgt_free_cmd --------------------->\n");
-
-		spin_lock_irq(&ha->hardware_lock);
-	}
-
-}
-
-
 /* ha->hardware_lock supposed to be held on entry */
 static void qla_tgt_free_session_done(struct qla_tgt_sess *sess)
 {
@@ -434,7 +379,6 @@ static void qla_tgt_free_session_done(struct qla_tgt_sess *sess)
 	tgt = sess->tgt;
 
 	sess->tearing_down = 1;
-	qla_tgt_wait_for_cmds(sess, ha);
 
 	/*
 	 * Release the target session for FC Nexus from fabric module code.
@@ -921,8 +865,6 @@ static struct qla_tgt_sess *qla_tgt_create_sess(
 	sess->loop_id = fcport->loop_id;
 	sess->local = local;
 
-	INIT_LIST_HEAD(&sess->sess_cmd_list);
-
 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xe109, "Adding sess %p to tgt %p via"
 		" ->check_initiator_node_acl()\n", sess, ha->qla_tgt);
 
@@ -3197,7 +3139,6 @@ static int qla_tgt_handle_cmd_for_atio(struct scsi_qla_host *vha, atio_t *atio)
 	}
 
 	INIT_LIST_HEAD(&cmd->cmd_list);
-	init_completion(&cmd->cmd_free_comp);
 	init_completion(&cmd->cmd_stop_free_comp);
 
 	memcpy(&cmd->atio.atio2x, atio, sizeof(*atio));
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 34ffe3c..96aa4e2 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -913,8 +913,6 @@ struct qla_tgt_sess {
 	unsigned long expires;
 	struct list_head del_list_entry;
 	
-	struct list_head sess_cmd_list; /* Protected by qla_hw_data->hardware_lock */
-
 	uint8_t port_name[WWN_SIZE];
 };
 
@@ -924,8 +922,6 @@ struct qla_tgt_cmd {
 	int locked_rsp;
 	atomic_t cmd_stop_free;
 	atomic_t cmd_free;
-	atomic_t cmd_free_comp_set;
-	struct completion cmd_free_comp;
 	struct completion cmd_stop_free_comp;
 	struct se_cmd se_cmd;
 	struct work_struct work_free;
diff --git a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c
index 0a51acc..d907c14 100644
--- a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c
+++ b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c
@@ -733,6 +733,15 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess)
 		dump_stack();
 		return;
 	}
+
+	target_splice_sess_cmd_list(se_sess);
+	spin_unlock_irq(&ha->hardware_lock);
+
+	target_wait_for_sess_cmds(se_sess, 0);
+
+	spin_lock_irq(&ha->hardware_lock);
+
+
 	/*
 	 * Now clear the struct se_node_acl->nacl_sess pointer
 	 */
@@ -1214,6 +1223,7 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = {
 	.tpg_get_inst_index		= tcm_qla2xxx_tpg_get_inst_index,
 	.new_cmd_map			= tcm_qla2xxx_new_cmd_map,
 	.check_stop_free		= tcm_qla2xxx_check_stop_free,
+	.check_release_cmd		= tcm_qla2xxx_check_release_cmd,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.shutdown_session		= tcm_qla2xxx_shutdown_session,
 	.close_session			= tcm_qla2xxx_close_session,
diff --git a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c
index 1aa8ee4..cb6d8bd 100644
--- a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c
+++ b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c
@@ -459,46 +459,16 @@ int tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd)
 	return 0;
 }
 
-/*
- * Called with qla_hw_data->hardware_lock held..
- */
-static int tcm_qla2xxx_release_shutdown_check(
-	struct qla_tgt_cmd *cmd,
-	struct qla_tgt_sess *sess)
-{
-	/*
-	 * During shutdown, qla_tgt_wait_for_cmds() will be waiting on
-	 * this outstanding qla_tgt_cmd descriptor.  For this case,
-	 * perform the completion and return, and qla_tgt_wait_for_cmds()
-	 * will handle the direct call to qla_tgt_free_cmd()
-	 */
-	if (cmd->tgt->tgt_stop || sess->tearing_down) {
-		if (atomic_read(&cmd->cmd_free_comp_set) ||
-		    atomic_read(&cmd->cmd_free)) {
-			pr_warn("Detected shutdown, calling complete("
-				"&cmd->cmd_free_comp): cmd: %p\n", cmd);
-			complete(&cmd->cmd_free_comp);
-			return 1;
-		}
-	}
-	list_del(&cmd->cmd_list);
-
-	return 0;
-}
-
-/*
- * Callback from TCM Core to release underlying fabric descriptor
- */
-void tcm_qla2xxx_release_cmd(struct se_cmd *se_cmd)
+int tcm_qla2xxx_check_release_cmd(struct se_cmd *se_cmd)
 {
 	struct qla_tgt_cmd *cmd;
 	struct qla_tgt_sess *sess;
 	struct qla_hw_data *ha;
 	unsigned long flags;
-	int ret;
+	int ret = 0;
 
 	if (se_cmd->se_tmr_req != NULL)
-		return;
+		return 0;
 
 	cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
 	sess = cmd->sess;
@@ -512,30 +482,39 @@ void tcm_qla2xxx_release_cmd(struct se_cmd *se_cmd)
 	 * exception path..  This also skips the possible wait for
 	 * completion on cmd_stop_free_comp below..
 	 */
-	if (!cmd->locked_rsp) {
-		if (!tcm_qla2xxx_release_shutdown_check(cmd, sess))
-			qla_tgt_free_cmd(cmd);	
-		return;
-	}
+	if (!cmd->locked_rsp)
+		return target_put_sess_cmd(sess->se_sess, se_cmd);
 	/*
 	 * If the callback to tcm_qla2xxx_check_stop_free() has not finished,
 	 * before the release path is invoked, go ahead and wait on
 	 * cmd_stop_free_comp until tcm_qla2xxx_check_stop_free completes.
 	 */
 	spin_lock_irqsave(&ha->hardware_lock, flags);
-	if ((atomic_read(&cmd->cmd_stop_free) != 1) &&
-	    (atomic_read(&cmd->cmd_free_comp_set) == 0)) {
+	if (atomic_read(&cmd->cmd_stop_free) != 1) {
 		pr_warn("Detected cmd->cmd_stop_free != 0, waiting on"
 			" cmd_stop_free_comp for cmd: %p\n", cmd);
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		wait_for_completion(&cmd->cmd_stop_free_comp);
 		spin_lock_irqsave(&ha->hardware_lock, flags);
 	}
-	ret = tcm_qla2xxx_release_shutdown_check(cmd, sess);
+	ret = target_put_sess_cmd(sess->se_sess, se_cmd);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-	if (!ret)
-		qla_tgt_free_cmd(cmd);
+	return ret;
+}
+
+/* tcm_qla2xxx_release_cmd - Callback from TCM Core to release underlying fabric descriptor
+ * @se_cmd command to release
+ */
+void tcm_qla2xxx_release_cmd(struct se_cmd *se_cmd)
+{
+	struct qla_tgt_cmd *cmd;
+
+	if (se_cmd->se_tmr_req != NULL)
+		return;
+
+	cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
+	qla_tgt_free_cmd(cmd);
 }
 
 int tcm_qla2xxx_shutdown_session(struct se_session *se_sess)
@@ -722,7 +701,7 @@ int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
 	/*
  	 * Protected by qla_hw_data->hardware_lock
  	 */
-	list_add_tail(&cmd->cmd_list, &sess->sess_cmd_list);
+	target_get_sess_cmd(se_sess, se_cmd);
 	/*
 	 * Signal BIDI usage with T_TASK(cmd)->t_tasks_bidi
 	 */
diff --git a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h
index ce166ac..e807a1e 100644
--- a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h
+++ b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h
@@ -26,6 +26,7 @@ extern void tcm_qla2xxx_release_fabric_acl(struct se_portal_group *, struct se_n
 extern u32 tcm_qla2xxx_tpg_get_inst_index(struct se_portal_group *);
 extern void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *);
 extern int tcm_qla2xxx_check_stop_free(struct se_cmd *);
+extern int tcm_qla2xxx_check_release_cmd(struct se_cmd *);
 extern void tcm_qla2xxx_release_cmd(struct se_cmd *);
 extern int tcm_qla2xxx_shutdown_session(struct se_session *);
 extern void tcm_qla2xxx_close_session(struct se_session *);
-- 
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