[PATCH v2 31/34] iser-target: Fix logout sequence

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

 



We don't want to wait for conn_logout_comp from isert_comp_wq
context as this blocks further completions from being processed.
Instead we wait for it conditionally (if logout response was
actually posted) in wait_conn. This wait should normally happen
immediately as it occurs after we consumed all the completions
(including flush errors) and conn_logout_comp should have been
completed.

Signed-off-by: Sagi Grimberg <sagig@xxxxxxxxxxxx>
---
 drivers/infiniband/ulp/isert/ib_isert.c |   34 ++++++++++++++++++++++--------
 drivers/infiniband/ulp/isert/ib_isert.h |    1 +
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index cc7377c..92f4b9f 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -1426,10 +1426,6 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc,
 			break;
 
 		ret = iscsit_handle_logout_cmd(conn, cmd, (unsigned char *)hdr);
-		if (ret > 0)
-			wait_for_completion_timeout(&conn->conn_logout_comp,
-						    SECONDS_FOR_LOGOUT_COMP *
-						    HZ);
 		break;
 	case ISCSI_OP_TEXT:
 		cmd = isert_allocate_cmd(conn);
@@ -1997,8 +1993,16 @@ isert_cq_comp_err(struct isert_conn *isert_conn, struct ib_wc *wc)
 		isert_cmd = desc->isert_cmd;
 		if (!isert_cmd)
 			isert_unmap_tx_desc(desc, ib_dev);
-		else
+		else {
+			struct iscsi_cmd *cmd = isert_cmd->iscsi_cmd;
+
+			if (cmd->i_state == ISTATE_SEND_LOGOUTRSP) {
+				pr_info("conn %p logout err comp\n",
+					   isert_conn);
+				complete(&isert_conn->conn->conn_logout_comp);
+			}
 			isert_completion_put(desc, isert_cmd, ib_dev, true);
+		}
 	} else {
 		isert_conn->post_recv_buf_count--;
 		if (!isert_conn->post_recv_buf_count)
@@ -2922,15 +2926,14 @@ isert_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state)
 static int
 isert_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state)
 {
+	struct isert_conn *isert_conn = conn->context;
 	int ret;
 
 	switch (state) {
 	case ISTATE_SEND_LOGOUTRSP:
 		ret = isert_put_logout_rsp(cmd, conn);
-		if (!ret) {
-			pr_debug("Returning iSER Logout -EAGAIN\n");
-			ret = -EAGAIN;
-		}
+		if (!ret)
+			isert_conn->logout_posted = true;
 		break;
 	case ISTATE_SEND_NOPIN:
 		ret = isert_put_nopin(cmd, conn, true);
@@ -3236,6 +3239,18 @@ static void isert_release_work(struct work_struct *work)
 }
 
 static void
+isert_wait4logout(struct isert_conn *isert_conn)
+{
+	struct iscsi_conn *conn = isert_conn->conn;
+
+	if (isert_conn->logout_posted) {
+		pr_info("conn %p wait for conn_logout_comp\n", isert_conn);
+		wait_for_completion_timeout(&conn->conn_logout_comp,
+					    SECONDS_FOR_LOGOUT_COMP * HZ);
+	}
+}
+
+static void
 isert_wait4cmds(struct iscsi_conn *conn)
 {
 	if (conn->sess) {
@@ -3280,6 +3295,7 @@ static void isert_wait_conn(struct iscsi_conn *conn)
 
 	isert_wait4cmds(conn);
 	isert_wait4flush(isert_conn);
+	isert_wait4logout(isert_conn);
 
 	INIT_WORK(&isert_conn->release_work, isert_release_work);
 	queue_work(isert_release_wq, &isert_conn->release_work);
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h
index 8ef1bd8..50837de 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.h
+++ b/drivers/infiniband/ulp/isert/ib_isert.h
@@ -156,6 +156,7 @@ struct isert_conn {
 	spinlock_t		conn_lock;
 	struct work_struct	release_work;
 	struct ib_recv_wr       beacon;
+	bool                    logout_posted;
 };
 
 #define ISERT_MAX_CQ 64
-- 
1.7.1

--
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