History

iscsi-target: Fix rx_login_comp hang after login failure

This patch addresses a case where iscsi_target_do_tx_login_io() fails sending the last login response PDU, after the RX/TX threads have already been started. The case centers around iscsi_target_rx_thread() not invoking allow_signal(SIGINT) before the send_sig(SIGINT, ...) occurs from the failure path, resulting in RX thread hanging indefinately on iscsi_conn->rx_login_comp. Note this bug is a regression introduced by: commit e54198657b65625085834847ab6271087323ffea Author: Nicholas Bellinger <nab@linux-iscsi.org> Date: Wed Jul 22 23:14:19 2015 -0700 iscsi-target: Fix iscsit_start_kthreads failure OOPs To address this bug, complete ->rx_login_complete for good measure in the failure path, and immediately return from RX thread context if connection state did not actually reach full feature phase (TARG_CONN_STATE_LOGGED_IN).

Nicholas Bellinger committed 11 years ago

Commit ca82c2b1 parent 82a819e2 files · +13 −1Browse files

Unified · Split

2 files
  1. drivers/target/iscsi/iscsi_target.c +12 −1
  2. drivers/target/iscsi/iscsi_target_nego.c +1 −0
drivers/target/iscsi/iscsi_target.c+12−1
@@ -4074,6 +4074,17 @@ reject: · 4073 unmodified lines
4074 return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);4074 return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
4075}4075}
4076 4076
4077static bool iscsi_target_check_conn_state(struct iscsi_conn *conn)
4078{
4079 bool ret;
4080
4081 spin_lock_bh(&conn->state_lock);
4082 ret = (conn->conn_state != TARG_CONN_STATE_LOGGED_IN);
4083 spin_unlock_bh(&conn->state_lock);
4084
4085 return ret;
4086}
4087
4077int iscsi_target_rx_thread(void *arg)4088int iscsi_target_rx_thread(void *arg)
4078{4089{
4079 int ret, rc;4090 int ret, rc;
@@ -4091,7 +4102,7 @@ int iscsi_target_rx_thread(void *arg) · 11 unmodified lines
4091 * incoming iscsi/tcp socket I/O, and/or failing the connection.4102 * incoming iscsi/tcp socket I/O, and/or failing the connection.
4092 */4103 */
4093 rc = wait_for_completion_interruptible(&conn->rx_login_comp);4104 rc = wait_for_completion_interruptible(&conn->rx_login_comp);
4094 if (rc < 0)4105 if (rc < 0 || iscsi_target_check_conn_state(conn))
4095 return 0;4106 return 0;
4096 4107
4097 if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) {4108 if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) {
drivers/target/iscsi/iscsi_target_nego.c+1−0
@@ -388,6 +388,7 @@ err: · 387 unmodified lines
388 if (login->login_complete) {388 if (login->login_complete) {
389 if (conn->rx_thread && conn->rx_thread_active) {389 if (conn->rx_thread && conn->rx_thread_active) {
390 send_sig(SIGINT, conn->rx_thread, 1);390 send_sig(SIGINT, conn->rx_thread, 1);
391 complete(&conn->rx_login_comp);
391 kthread_stop(conn->rx_thread);392 kthread_stop(conn->rx_thread);
392 }393 }
393 if (conn->tx_thread && conn->tx_thread_active) {394 if (conn->tx_thread && conn->tx_thread_active) {