diff mbox

[2/4] iscsi target: make iscsit_cause_connection_reinstatement interruptible

Message ID 1488164640-8751-3-git-send-email-mchristi@redhat.com (mailing list archive)
State Superseded
Headers show

Commit Message

Mike Christie Feb. 27, 2017, 3:03 a.m. UTC
To handle initiators dropping tcp connections while the login
process is waiting on connections getting cleaned up, we need
to make that login path interruptible. This patch modifies
iscsit_cause_connection_reinstatement.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/infiniband/ulp/isert/ib_isert.c  | 12 ++++++------
 drivers/target/iscsi/iscsi_target.c      | 19 +++++++++++++------
 drivers/target/iscsi/iscsi_target_erl0.c | 23 +++++++++++++++++------
 drivers/target/iscsi/iscsi_target_erl0.h |  2 +-
 drivers/target/iscsi/iscsi_target_erl1.c |  2 +-
 drivers/target/iscsi/iscsi_target_util.c |  2 +-
 include/target/iscsi/iscsi_transport.h   |  2 +-
 7 files changed, 40 insertions(+), 22 deletions(-)
diff mbox

Patch

diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 314e955..c80a18c 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -725,7 +725,7 @@ 
 		break;
 	case ISER_CONN_BOUND:
 	case ISER_CONN_FULL_FEATURE: /* FALLTHRU */
-		iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
+		iscsit_cause_connection_reinstatement(isert_conn->conn, 0, 0);
 		break;
 	default:
 		isert_warn("conn %p teminating in state %d\n",
@@ -1393,7 +1393,7 @@ 
 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
 		isert_print_wc(wc, "recv");
 		if (wc->status != IB_WC_WR_FLUSH_ERR)
-			iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
+			iscsit_cause_connection_reinstatement(isert_conn->conn, 0, 0);
 		return;
 	}
 
@@ -1649,7 +1649,7 @@ 
 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
 		isert_print_wc(wc, "rdma write");
 		if (wc->status != IB_WC_WR_FLUSH_ERR)
-			iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
+			iscsit_cause_connection_reinstatement(isert_conn->conn, 0, 0);
 		isert_completion_put(desc, isert_cmd, device->ib_device, true);
 		return;
 	}
@@ -1679,7 +1679,7 @@ 
 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
 		isert_print_wc(wc, "rdma read");
 		if (wc->status != IB_WC_WR_FLUSH_ERR)
-			iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
+			iscsit_cause_connection_reinstatement(isert_conn->conn, 0, 0);
 		isert_completion_put(desc, isert_cmd, device->ib_device, true);
 		return;
 	}
@@ -1748,7 +1748,7 @@ 
 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
 		isert_print_wc(wc, "login send");
 		if (wc->status != IB_WC_WR_FLUSH_ERR)
-			iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
+			iscsit_cause_connection_reinstatement(isert_conn->conn, 0, 0);
 	}
 
 	isert_unmap_tx_desc(tx_desc, ib_dev);
@@ -1765,7 +1765,7 @@ 
 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
 		isert_print_wc(wc, "send");
 		if (wc->status != IB_WC_WR_FLUSH_ERR)
-			iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
+			iscsit_cause_connection_reinstatement(isert_conn->conn, 0, 0);
 		isert_completion_put(tx_desc, isert_cmd, ib_dev, true);
 		return;
 	}
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 4328036..a2e6a4f 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -4448,7 +4448,7 @@  static void iscsit_logout_post_handler_samecid(
 	atomic_set(&conn->conn_logout_remove, 0);
 	complete(&conn->conn_logout_comp);
 
-	iscsit_cause_connection_reinstatement(conn, sleep);
+	iscsit_cause_connection_reinstatement(conn, sleep, 0);
 	iscsit_dec_conn_usage_count(conn);
 }
 
@@ -4484,7 +4484,7 @@  static void iscsit_logout_post_handler_diffcid(
 	l_conn->conn_state = TARG_CONN_STATE_IN_LOGOUT;
 	spin_unlock_bh(&l_conn->state_lock);
 
-	iscsit_cause_connection_reinstatement(l_conn, 1);
+	iscsit_cause_connection_reinstatement(l_conn, 1, 0);
 	iscsit_dec_conn_usage_count(l_conn);
 }
 
@@ -4589,7 +4589,7 @@  int iscsit_free_session(struct iscsi_session *sess)
 		iscsit_inc_conn_usage_count(conn);
 
 		spin_unlock_bh(&sess->conn_lock);
-		iscsit_cause_connection_reinstatement(conn, 1);
+		iscsit_cause_connection_reinstatement(conn, 1, 0);
 		spin_lock_bh(&sess->conn_lock);
 
 		iscsit_dec_conn_usage_count(conn);
@@ -4617,7 +4617,7 @@  int iscsit_stop_session(
 {
 	u16 conn_count = atomic_read(&sess->nconn);
 	struct iscsi_conn *conn, *conn_tmp = NULL;
-	int is_last;
+	int is_last, ret;
 
 	spin_lock_bh(&sess->conn_lock);
 	if (session_sleep)
@@ -4638,17 +4638,24 @@  int iscsit_stop_session(
 			iscsit_inc_conn_usage_count(conn);
 
 			spin_unlock_bh(&sess->conn_lock);
-			iscsit_cause_connection_reinstatement(conn, 1);
+			ret = iscsit_cause_connection_reinstatement(conn, 1,
+								interruptible);
 			spin_lock_bh(&sess->conn_lock);
 
 			iscsit_dec_conn_usage_count(conn);
 			if (is_last == 0)
 				iscsit_dec_conn_usage_count(conn_tmp);
+
+			if (ret) {
+				spin_unlock_bh(&sess->conn_lock);
+				return -1;
+			}
+
 			conn_count--;
 		}
 	} else {
 		list_for_each_entry(conn, &sess->sess_conn_list, conn_list)
-			iscsit_cause_connection_reinstatement(conn, 0);
+			iscsit_cause_connection_reinstatement(conn, 0, 0);
 	}
 
 	if (session_sleep && atomic_read(&sess->nconn)) {
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c
index a8bcbc4..42f3610 100644
--- a/drivers/target/iscsi/iscsi_target_erl0.c
+++ b/drivers/target/iscsi/iscsi_target_erl0.c
@@ -867,22 +867,25 @@  void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *conn)
 	complete(&conn->conn_post_wait_comp);
 }
 
-void iscsit_cause_connection_reinstatement(struct iscsi_conn *conn, int sleep)
+int iscsit_cause_connection_reinstatement(struct iscsi_conn *conn, int sleep,
+					  int interruptible)
 {
+	int ret = 0;
+
 	spin_lock_bh(&conn->state_lock);
 	if (atomic_read(&conn->connection_exit)) {
 		spin_unlock_bh(&conn->state_lock);
-		return;
+		return 0;
 	}
 
 	if (atomic_read(&conn->transport_failed)) {
 		spin_unlock_bh(&conn->state_lock);
-		return;
+		return 0;
 	}
 
 	if (atomic_read(&conn->connection_reinstatement)) {
 		spin_unlock_bh(&conn->state_lock);
-		return;
+		return 0;
 	}
 
 	if (conn->tx_thread && conn->tx_thread_active)
@@ -893,14 +896,22 @@  void iscsit_cause_connection_reinstatement(struct iscsi_conn *conn, int sleep)
 	atomic_set(&conn->connection_reinstatement, 1);
 	if (!sleep) {
 		spin_unlock_bh(&conn->state_lock);
-		return;
+		return 0;
 	}
 
 	atomic_set(&conn->sleep_on_conn_wait_comp, 1);
 	spin_unlock_bh(&conn->state_lock);
 
-	wait_for_completion(&conn->conn_wait_comp);
+	if (interruptible)
+		ret = wait_for_completion_interruptible(&conn->conn_wait_comp);
+	else
+		wait_for_completion(&conn->conn_wait_comp);
+
 	complete(&conn->conn_post_wait_comp);
+	if (ret == -ERESTARTSYS)
+		return -1;
+
+	return 0;
 }
 EXPORT_SYMBOL(iscsit_cause_connection_reinstatement);
 
diff --git a/drivers/target/iscsi/iscsi_target_erl0.h b/drivers/target/iscsi/iscsi_target_erl0.h
index 60e69e2..1c71fb0 100644
--- a/drivers/target/iscsi/iscsi_target_erl0.h
+++ b/drivers/target/iscsi/iscsi_target_erl0.h
@@ -13,7 +13,7 @@ 
 extern void iscsit_start_time2retain_handler(struct iscsi_session *);
 extern int iscsit_stop_time2retain_timer(struct iscsi_session *);
 extern void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *);
-extern void iscsit_cause_connection_reinstatement(struct iscsi_conn *, int);
+extern int iscsit_cause_connection_reinstatement(struct iscsi_conn *, int, int);
 extern void iscsit_fall_back_to_erl0(struct iscsi_session *);
 extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *);
 
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c
index fe9b7f1..5cbccce 100644
--- a/drivers/target/iscsi/iscsi_target_erl1.c
+++ b/drivers/target/iscsi/iscsi_target_erl1.c
@@ -1225,7 +1225,7 @@  static void iscsit_handle_dataout_timeout(unsigned long data)
 
 failure:
 	spin_unlock_bh(&cmd->dataout_timeout_lock);
-	iscsit_cause_connection_reinstatement(conn, 0);
+	iscsit_cause_connection_reinstatement(conn, 0, 0);
 	iscsit_dec_conn_usage_count(conn);
 }
 
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index f46eadf..ec11318 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -946,7 +946,7 @@  static void iscsit_handle_nopin_response_timeout(unsigned long data)
 	}
 	}
 
-	iscsit_cause_connection_reinstatement(conn, 0);
+	iscsit_cause_connection_reinstatement(conn, 0, 0);
 	iscsit_dec_conn_usage_count(conn);
 }
 
diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h
index ff1a4f4..b9a76ed 100644
--- a/include/target/iscsi/iscsi_transport.h
+++ b/include/target/iscsi/iscsi_transport.h
@@ -108,7 +108,7 @@  extern int iscsit_build_r2ts_for_cmd(struct iscsi_conn *, struct iscsi_cmd *,
 /*
  * From iscsi_target_erl0.c
  */
-extern void iscsit_cause_connection_reinstatement(struct iscsi_conn *, int);
+extern int iscsit_cause_connection_reinstatement(struct iscsi_conn *, int, int);
 /*
  * From iscsi_target_erl1.c
  */