Do not lock istate_lock except directly around i_state modifications. Put entire ISTATE_SEND_DATAIN path within first switch statement, in prep for further refactoring. All other cases set use_misc = 1 and will not be using sendpage, so just use send_tx_data for these and set use_misc param to 1. map_sg, sent_status, use_misc, and se_cmd vars no longer needed. Signed-off-by: Andy Grover <agrover@xxxxxxxxxx> --- drivers/target/iscsi/iscsi_target.c | 158 ++++++++++++++--------------------- 1 files changed, 63 insertions(+), 95 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 2f44af8..c0e839a 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -2433,10 +2433,19 @@ static int iscsit_send_conn_drop_async_message( return 0; } +static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn) +{ + if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) || + (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) { + wait_for_completion_interruptible_timeout( + &conn->tx_half_close_comp, + ISCSI_TX_THREAD_TCP_TIMEOUT * HZ); + } +} + static int iscsit_send_data_in( struct iscsi_cmd *cmd, - struct iscsi_conn *conn, - int *eodr) + struct iscsi_conn *conn) { int iov_ret = 0, set_statsn = 0; u32 iov_count = 0, tx_size = 0; @@ -2444,6 +2453,8 @@ static int iscsit_send_data_in( struct iscsi_datain_req *dr; struct iscsi_data_rsp *hdr; struct kvec *iov; + int eodr = 0; + int ret; memset(&datain, 0, sizeof(struct iscsi_datain)); dr = iscsit_get_datain_values(cmd, &datain); @@ -2576,13 +2587,26 @@ static int iscsit_send_data_in( cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn), ntohl(hdr->offset), datain.length, conn->cid); + /* sendpage is preferred but can't insert markers */ + if (!conn->conn_ops->IFMarker) + ret = iscsit_fe_sendpage_sg(cmd, conn); + else + ret = iscsit_send_tx_data(cmd, conn, 0); + + iscsit_unmap_iovec(cmd); + + if (ret < 0) { + iscsit_tx_thread_wait_for_tcp(conn); + return ret; + } + if (dr->dr_complete) { - *eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ? + eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ? 2 : 1; iscsit_free_datain_req(cmd, dr); } - return 0; + return eodr; } static int iscsit_send_logout_response( @@ -2704,16 +2728,6 @@ static int iscsit_send_logout_response( return 0; } -static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn) -{ - if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) || - (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) { - wait_for_completion_interruptible_timeout( - &conn->tx_half_close_comp, - ISCSI_TX_THREAD_TCP_TIMEOUT * HZ); - } -} - /* * Unsolicited NOPIN, either requesting a response or not. */ @@ -3497,11 +3511,7 @@ static inline void iscsit_thread_check_cpumask( int iscsi_target_tx_thread(void *arg) { u8 state; - int eodr = 0; int ret = 0; - int sent_status = 0; - int use_misc = 0; - int map_sg = 0; struct iscsi_cmd *cmd = NULL; struct iscsi_conn *conn; struct iscsi_queue_req *qr = NULL; @@ -3517,7 +3527,7 @@ restart: if (!conn) goto out; - eodr = map_sg = ret = sent_status = use_misc = 0; + ret = 0; while (!kthread_should_stop()) { /* @@ -3581,45 +3591,50 @@ restart: state = qr->state; kmem_cache_free(lio_qr_cache, qr); - spin_lock_bh(&cmd->istate_lock); check_rsp_state: switch (state) { case ISTATE_SEND_DATAIN: - spin_unlock_bh(&cmd->istate_lock); - ret = iscsit_send_data_in(cmd, conn, - &eodr); - map_sg = 1; + ret = iscsit_send_data_in(cmd, conn); + if (ret < 0) + goto transport_err; + else if (!ret) + /* more drs */ + goto check_rsp_state; + else if (ret == 1) { + /* all done */ + spin_lock_bh(&cmd->istate_lock); + cmd->i_state = ISTATE_SENT_STATUS; + spin_unlock_bh(&cmd->istate_lock); + continue; + } else if (ret == 2) { + /* Still must send status, + SCF_TRANSPORT_TASK_SENSE was set */ + spin_lock_bh(&cmd->istate_lock); + cmd->i_state = ISTATE_SEND_STATUS; + spin_unlock_bh(&cmd->istate_lock); + state = ISTATE_SEND_STATUS; + goto check_rsp_state; + } + break; case ISTATE_SEND_STATUS: case ISTATE_SEND_STATUS_RECOVERY: - spin_unlock_bh(&cmd->istate_lock); - use_misc = 1; ret = iscsit_send_status(cmd, conn); break; case ISTATE_SEND_LOGOUTRSP: - spin_unlock_bh(&cmd->istate_lock); - use_misc = 1; ret = iscsit_send_logout_response(cmd, conn); break; case ISTATE_SEND_ASYNCMSG: - spin_unlock_bh(&cmd->istate_lock); - use_misc = 1; ret = iscsit_send_conn_drop_async_message( cmd, conn); break; case ISTATE_SEND_NOPIN: - spin_unlock_bh(&cmd->istate_lock); - use_misc = 1; ret = iscsit_send_nopin_response(cmd, conn); break; case ISTATE_SEND_REJECT: - spin_unlock_bh(&cmd->istate_lock); - use_misc = 1; ret = iscsit_send_reject(cmd, conn); break; case ISTATE_SEND_TASKMGTRSP: - spin_unlock_bh(&cmd->istate_lock); - use_misc = 1; ret = iscsit_send_task_mgt_rsp(cmd, conn); if (ret != 0) break; @@ -3628,8 +3643,6 @@ check_rsp_state: iscsit_fall_back_to_erl0(conn->sess); break; case ISTATE_SEND_TEXTRSP: - spin_unlock_bh(&cmd->istate_lock); - use_misc = 1; ret = iscsit_send_text_rsp(cmd, conn); break; default: @@ -3637,94 +3650,49 @@ check_rsp_state: " 0x%08x, i_state: %d on CID: %hu\n", cmd->iscsi_opcode, cmd->init_task_tag, state, conn->cid); - spin_unlock_bh(&cmd->istate_lock); goto transport_err; } if (ret < 0) goto transport_err; - if (map_sg && !conn->conn_ops->IFMarker) { - if (iscsit_fe_sendpage_sg(cmd, conn) < 0) { - iscsit_tx_thread_wait_for_tcp(conn); - iscsit_unmap_iovec(cmd); - goto transport_err; - } - } else { - if (iscsit_send_tx_data(cmd, conn, use_misc) < 0) { - iscsit_tx_thread_wait_for_tcp(conn); - iscsit_unmap_iovec(cmd); - goto transport_err; - } + if (iscsit_send_tx_data(cmd, conn, 1) < 0) { + iscsit_tx_thread_wait_for_tcp(conn); + iscsit_unmap_iovec(cmd); + goto transport_err; } - map_sg = 0; iscsit_unmap_iovec(cmd); - spin_lock_bh(&cmd->istate_lock); switch (state) { - case ISTATE_SEND_DATAIN: - if (!eodr) - goto check_rsp_state; - - if (eodr == 1) { - cmd->i_state = ISTATE_SENT_LAST_DATAIN; - sent_status = 1; - eodr = use_misc = 0; - } else if (eodr == 2) { - cmd->i_state = state = - ISTATE_SEND_STATUS; - sent_status = 0; - eodr = use_misc = 0; - goto check_rsp_state; - } - break; + case ISTATE_SEND_LOGOUTRSP: + if (!iscsit_logout_post_handler(cmd, conn)) + goto restart; + /* fall through */ case ISTATE_SEND_STATUS: - use_misc = 0; - sent_status = 1; - break; case ISTATE_SEND_ASYNCMSG: case ISTATE_SEND_NOPIN: case ISTATE_SEND_STATUS_RECOVERY: case ISTATE_SEND_TEXTRSP: - use_misc = 0; - sent_status = 1; + case ISTATE_SEND_TASKMGTRSP: + spin_lock_bh(&cmd->istate_lock); + cmd->i_state = ISTATE_SENT_STATUS; + spin_unlock_bh(&cmd->istate_lock); break; case ISTATE_SEND_REJECT: - use_misc = 0; if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) { cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN; - spin_unlock_bh(&cmd->istate_lock); complete(&cmd->reject_comp); goto transport_err; } complete(&cmd->reject_comp); break; - case ISTATE_SEND_TASKMGTRSP: - use_misc = 0; - sent_status = 1; - break; - case ISTATE_SEND_LOGOUTRSP: - spin_unlock_bh(&cmd->istate_lock); - if (!iscsit_logout_post_handler(cmd, conn)) - goto restart; - spin_lock_bh(&cmd->istate_lock); - use_misc = 0; - sent_status = 1; - break; default: pr_err("Unknown Opcode: 0x%02x ITT:" " 0x%08x, i_state: %d on CID: %hu\n", cmd->iscsi_opcode, cmd->init_task_tag, cmd->i_state, conn->cid); - spin_unlock_bh(&cmd->istate_lock); goto transport_err; } - if (sent_status) { - cmd->i_state = ISTATE_SENT_STATUS; - sent_status = 0; - } - spin_unlock_bh(&cmd->istate_lock); - if (atomic_read(&conn->check_immediate_queue)) break; } -- 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