public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] target: Re-instate sess_wait_list usage
@ 2013-05-18  0:40 Nicholas A. Bellinger
  2013-05-18  0:40 ` [PATCH 1/3] target: Remove unused wait_for_tasks bit in target_wait_for_sess_cmds Nicholas A. Bellinger
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Nicholas A. Bellinger @ 2013-05-18  0:40 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, linux-kernel, Roland Dreier, Joern Engel,
	Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

Hi folks,

Here's a short series to re-instate the original sess_wait_list to pre
commit 1c7b13fe652 logic, along with the necessary changes to function
within ib_srpt code during active I/O shutdown.

This has been tested with ib_srpt, but still needs to be verified with
tcm_qla2xxx during active I/O shutdown.

Thanks,

--nab

Joern Engel (1):
  target: Remove unused wait_for_tasks bit in target_wait_for_sess_cmds

Nicholas Bellinger (2):
  target: Re-instate sess_wait_list for target_wait_for_sess_cmds
  ib_srpt: Call target_sess_cmd_list_set_waiting during
    shutdown_session

 drivers/infiniband/ulp/srpt/ib_srpt.c  |   34 +++++++++++++++++------
 drivers/infiniband/ulp/srpt/ib_srpt.h  |    1 +
 drivers/scsi/qla2xxx/tcm_qla2xxx.c     |    2 +-
 drivers/target/target_core_transport.c |   46 +++++++++++++------------------
 include/target/target_core_base.h      |    1 +
 include/target/target_core_fabric.h    |    2 +-
 6 files changed, 48 insertions(+), 38 deletions(-)

-- 
1.7.2.5

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] target: Remove unused wait_for_tasks bit in target_wait_for_sess_cmds
  2013-05-18  0:40 [PATCH 0/3] target: Re-instate sess_wait_list usage Nicholas A. Bellinger
@ 2013-05-18  0:40 ` Nicholas A. Bellinger
  2013-05-18  0:40 ` [PATCH 2/3] target: Re-instate sess_wait_list for target_wait_for_sess_cmds Nicholas A. Bellinger
  2013-05-18  0:40 ` [PATCH 3/3] ib_srpt: Call target_sess_cmd_list_set_waiting during shutdown_session Nicholas A. Bellinger
  2 siblings, 0 replies; 4+ messages in thread
From: Nicholas A. Bellinger @ 2013-05-18  0:40 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, linux-kernel, Roland Dreier, Joern Engel

From: Joern Engel <joern@logfs.org>

Drop unused transport_wait_for_tasks() check in target_wait_for_sess_cmds
shutdown code, and convert tcm_qla2xxx + ib_srpt fabric drivers.

Cc: Joern Engel <joern@logfs.org>
Cc: Roland Dreier <roland@kernel.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c  |    2 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c     |    2 +-
 drivers/target/target_core_transport.c |   28 +++++-----------------------
 include/target/target_core_fabric.h    |    2 +-
 4 files changed, 8 insertions(+), 26 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index c09d41b..c318f7c 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -2328,7 +2328,7 @@ static void srpt_release_channel_work(struct work_struct *w)
 	se_sess = ch->sess;
 	BUG_ON(!se_sess);
 
-	target_wait_for_sess_cmds(se_sess, 0);
+	target_wait_for_sess_cmds(se_sess);
 
 	transport_deregister_session_configfs(se_sess);
 	transport_deregister_session(se_sess);
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index d182c96..7a3870f 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -1370,7 +1370,7 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess)
 		dump_stack();
 		return;
 	}
-	target_wait_for_sess_cmds(se_sess, 0);
+	target_wait_for_sess_cmds(se_sess);
 
 	transport_deregister_session_configfs(sess->se_sess);
 	transport_deregister_session(sess->se_sess);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 4a79336..311c113 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2263,14 +2263,10 @@ EXPORT_SYMBOL(target_sess_cmd_list_set_waiting);
 
 /* target_wait_for_sess_cmds - Wait for outstanding descriptors
  * @se_sess:    session to wait for active I/O
- * @wait_for_tasks:	Make extra transport_wait_for_tasks call
  */
-void target_wait_for_sess_cmds(
-	struct se_session *se_sess,
-	int wait_for_tasks)
+void target_wait_for_sess_cmds(struct se_session *se_sess)
 {
 	struct se_cmd *se_cmd, *tmp_cmd;
-	bool rc = false;
 
 	list_for_each_entry_safe(se_cmd, tmp_cmd,
 				&se_sess->sess_cmd_list, se_cmd_list) {
@@ -2280,24 +2276,10 @@ void target_wait_for_sess_cmds(
 			" %d\n", se_cmd, se_cmd->t_state,
 			se_cmd->se_tfo->get_cmd_state(se_cmd));
 
-		if (wait_for_tasks) {
-			pr_debug("Calling transport_wait_for_tasks se_cmd: %p t_state: %d,"
-				" fabric state: %d\n", se_cmd, se_cmd->t_state,
-				se_cmd->se_tfo->get_cmd_state(se_cmd));
-
-			rc = transport_wait_for_tasks(se_cmd);
-
-			pr_debug("After transport_wait_for_tasks se_cmd: %p t_state: %d,"
-				" fabric state: %d\n", se_cmd, se_cmd->t_state,
-				se_cmd->se_tfo->get_cmd_state(se_cmd));
-		}
-
-		if (!rc) {
-			wait_for_completion(&se_cmd->cmd_wait_comp);
-			pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d"
-				" fabric state: %d\n", se_cmd, se_cmd->t_state,
-				se_cmd->se_tfo->get_cmd_state(se_cmd));
-		}
+		wait_for_completion(&se_cmd->cmd_wait_comp);
+		pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d"
+			" fabric state: %d\n", se_cmd, se_cmd->t_state,
+			se_cmd->se_tfo->get_cmd_state(se_cmd));
 
 		se_cmd->se_tfo->release_cmd(se_cmd);
 	}
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index ba3471b..8a26f0d 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -123,7 +123,7 @@ int	transport_send_check_condition_and_sense(struct se_cmd *,
 int	target_get_sess_cmd(struct se_session *, struct se_cmd *, bool);
 int	target_put_sess_cmd(struct se_session *, struct se_cmd *);
 void	target_sess_cmd_list_set_waiting(struct se_session *);
-void	target_wait_for_sess_cmds(struct se_session *, int);
+void	target_wait_for_sess_cmds(struct se_session *);
 
 int	core_alua_check_nonop_delay(struct se_cmd *);
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] target: Re-instate sess_wait_list for target_wait_for_sess_cmds
  2013-05-18  0:40 [PATCH 0/3] target: Re-instate sess_wait_list usage Nicholas A. Bellinger
  2013-05-18  0:40 ` [PATCH 1/3] target: Remove unused wait_for_tasks bit in target_wait_for_sess_cmds Nicholas A. Bellinger
@ 2013-05-18  0:40 ` Nicholas A. Bellinger
  2013-05-18  0:40 ` [PATCH 3/3] ib_srpt: Call target_sess_cmd_list_set_waiting during shutdown_session Nicholas A. Bellinger
  2 siblings, 0 replies; 4+ messages in thread
From: Nicholas A. Bellinger @ 2013-05-18  0:40 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, linux-kernel, Roland Dreier, Joern Engel,
	Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

Switch back to pre commit 1c7b13fe652 list splicing logic for active I/O
shutdown with tcm_qla2xxx + ib_srpt fabrics.

The original commit was done under the incorrect assumption that it's safe to
walk se_sess->sess_cmd_list unprotected in target_wait_for_sess_cmds() after
sess->sess_tearing_down = 1 has been set by target_sess_cmd_list_set_waiting()
during session shutdown.

So instead of adding sess->sess_cmd_lock protection around sess->sess_cmd_list
during target_wait_for_sess_cmds(), switch back to sess->sess_wait_list to
allow wait_for_completion() + TFO->release_cmd() to occur without having to
walk ->sess_cmd_list after the list_splice.

Also add a check to exit if target_sess_cmd_list_set_waiting() has already
been called, and add a WARN_ON to check for any fabric bug where new se_cmds
are added to sess->sess_cmd_list after sess->sess_tearing_down = 1 has already
been set.

Cc: Joern Engel <joern@logfs.org>
Cc: Roland Dreier <roland@kernel.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |   18 ++++++++++++++----
 include/target/target_core_base.h      |    1 +
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 311c113..bbca144 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -221,6 +221,7 @@ struct se_session *transport_init_session(void)
 	INIT_LIST_HEAD(&se_sess->sess_list);
 	INIT_LIST_HEAD(&se_sess->sess_acl_list);
 	INIT_LIST_HEAD(&se_sess->sess_cmd_list);
+	INIT_LIST_HEAD(&se_sess->sess_wait_list);
 	spin_lock_init(&se_sess->sess_cmd_lock);
 	kref_init(&se_sess->sess_kref);
 
@@ -2250,11 +2251,14 @@ void target_sess_cmd_list_set_waiting(struct se_session *se_sess)
 	unsigned long flags;
 
 	spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
-
-	WARN_ON(se_sess->sess_tearing_down);
+	if (se_sess->sess_tearing_down) {
+		spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+		return;
+	}
 	se_sess->sess_tearing_down = 1;
+	list_splice_init(&se_sess->sess_cmd_list, &se_sess->sess_wait_list);
 
-	list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list)
+	list_for_each_entry(se_cmd, &se_sess->sess_wait_list, se_cmd_list)
 		se_cmd->cmd_wait_set = 1;
 
 	spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
@@ -2267,9 +2271,10 @@ EXPORT_SYMBOL(target_sess_cmd_list_set_waiting);
 void target_wait_for_sess_cmds(struct se_session *se_sess)
 {
 	struct se_cmd *se_cmd, *tmp_cmd;
+	unsigned long flags;
 
 	list_for_each_entry_safe(se_cmd, tmp_cmd,
-				&se_sess->sess_cmd_list, se_cmd_list) {
+				&se_sess->sess_wait_list, se_cmd_list) {
 		list_del(&se_cmd->se_cmd_list);
 
 		pr_debug("Waiting for se_cmd: %p t_state: %d, fabric state:"
@@ -2283,6 +2288,11 @@ void target_wait_for_sess_cmds(struct se_session *se_sess)
 
 		se_cmd->se_tfo->release_cmd(se_cmd);
 	}
+
+	spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
+	WARN_ON(!list_empty(&se_sess->sess_cmd_list));
+	spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+
 }
 EXPORT_SYMBOL(target_wait_for_sess_cmds);
 
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index e773dfa..4ea4f98 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -543,6 +543,7 @@ struct se_session {
 	struct list_head	sess_list;
 	struct list_head	sess_acl_list;
 	struct list_head	sess_cmd_list;
+	struct list_head	sess_wait_list;
 	spinlock_t		sess_cmd_lock;
 	struct kref		sess_kref;
 };
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] ib_srpt: Call target_sess_cmd_list_set_waiting during shutdown_session
  2013-05-18  0:40 [PATCH 0/3] target: Re-instate sess_wait_list usage Nicholas A. Bellinger
  2013-05-18  0:40 ` [PATCH 1/3] target: Remove unused wait_for_tasks bit in target_wait_for_sess_cmds Nicholas A. Bellinger
  2013-05-18  0:40 ` [PATCH 2/3] target: Re-instate sess_wait_list for target_wait_for_sess_cmds Nicholas A. Bellinger
@ 2013-05-18  0:40 ` Nicholas A. Bellinger
  2 siblings, 0 replies; 4+ messages in thread
From: Nicholas A. Bellinger @ 2013-05-18  0:40 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, linux-kernel, Roland Dreier, Joern Engel,
	Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

Given that srpt_release_channel_work() calls target_wait_for_sess_cmds()
to allow outstanding se_cmd_t->cmd_kref a change to complete, the call
to perform target_sess_cmd_list_set_waiting() needs to happen in
srpt_shutdown_session()

Also, this patch adds an explicit call to srpt_shutdown_session() within
srpt_drain_channel() so that target_sess_cmd_list_set_waiting() will be
called in the cases where TFO->shutdown_session() is not triggered
directly by TCM.

Cc: Joern Engel <joern@logfs.org>
Cc: Roland Dreier <roland@kernel.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c |   32 ++++++++++++++++++++++++--------
 drivers/infiniband/ulp/srpt/ib_srpt.h |    1 +
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index c318f7c..824b704 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -2227,6 +2227,27 @@ static void srpt_close_ch(struct srpt_rdma_ch *ch)
 }
 
 /**
+ * srpt_shutdown_session() - Whether or not a session may be shut down.
+ */
+static int srpt_shutdown_session(struct se_session *se_sess)
+{
+	struct srpt_rdma_ch *ch = se_sess->fabric_sess_ptr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ch->spinlock, flags);
+	if (ch->in_shutdown) {
+		spin_unlock_irqrestore(&ch->spinlock, flags);
+		return true;
+	}
+
+	ch->in_shutdown = true;
+	target_sess_cmd_list_set_waiting(se_sess);
+	spin_unlock_irqrestore(&ch->spinlock, flags);
+
+	return true;
+}
+
+/**
  * srpt_drain_channel() - Drain a channel by resetting the IB queue pair.
  * @cm_id: Pointer to the CM ID of the channel to be drained.
  *
@@ -2264,6 +2285,9 @@ static void srpt_drain_channel(struct ib_cm_id *cm_id)
 	spin_unlock_irq(&sdev->spinlock);
 
 	if (do_reset) {
+		if (ch->sess)
+			srpt_shutdown_session(ch->sess);
+
 		ret = srpt_ch_qp_err(ch);
 		if (ret < 0)
 			printk(KERN_ERR "Setting queue pair in error state"
@@ -3467,14 +3491,6 @@ static void srpt_release_cmd(struct se_cmd *se_cmd)
 }
 
 /**
- * srpt_shutdown_session() - Whether or not a session may be shut down.
- */
-static int srpt_shutdown_session(struct se_session *se_sess)
-{
-	return true;
-}
-
-/**
  * srpt_close_session() - Forcibly close a session.
  *
  * Callback function invoked by the TCM core to clean up sessions associated
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h
index 4caf55c..3dae156 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.h
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.h
@@ -325,6 +325,7 @@ struct srpt_rdma_ch {
 	u8			sess_name[36];
 	struct work_struct	release_work;
 	struct completion	*release_done;
+	bool			in_shutdown;
 };
 
 /**
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-05-18  0:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-05-18  0:40 [PATCH 0/3] target: Re-instate sess_wait_list usage Nicholas A. Bellinger
2013-05-18  0:40 ` [PATCH 1/3] target: Remove unused wait_for_tasks bit in target_wait_for_sess_cmds Nicholas A. Bellinger
2013-05-18  0:40 ` [PATCH 2/3] target: Re-instate sess_wait_list for target_wait_for_sess_cmds Nicholas A. Bellinger
2013-05-18  0:40 ` [PATCH 3/3] ib_srpt: Call target_sess_cmd_list_set_waiting during shutdown_session Nicholas A. Bellinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox