@@ -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;
}
@@ -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)) {
@@ -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);
@@ -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 *);
@@ -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);
}
@@ -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);
}
@@ -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
*/
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(-)