diff --git a/iscsi-scst/kernel/conn.c b/iscsi-scst/kernel/conn.c index d887d58a8..d6040f62f 100644 --- a/iscsi-scst/kernel/conn.c +++ b/iscsi-scst/kernel/conn.c @@ -621,7 +621,8 @@ void iscsi_check_tm_data_wait_timeouts(struct iscsi_conn *conn, bool force) TRACE_ENTRY(); TRACE_DBG_FLAG(force ? TRACE_CONN_OC_DBG : TRACE_MGMT_DEBUG, - "j %ld (TIMEOUT %d, force %d)", j, + "conn %p, read_cmnd %p, read_state %d, j %ld (TIMEOUT %d, " + "force %d)", conn, conn->read_cmnd, conn->read_state, j, ISCSI_TM_DATA_WAIT_TIMEOUT + ISCSI_ADD_SCHED_TIME, force); iscsi_extracheck_is_rd_thread(conn); @@ -637,17 +638,38 @@ again: TRACE_DBG_FLAG(force ? TRACE_CONN_OC_DBG : TRACE_MGMT_DEBUG, "Checking aborted cmnd %p (scst_state %d, " "on_write_timeout_list %d, write_start %ld, " - "r2t_len_to_receive %d)", cmnd, - cmnd->scst_state, cmnd->on_write_timeout_list, - cmnd->write_start, cmnd->r2t_len_to_receive); - if ((cmnd->r2t_len_to_receive != 0) && + "r2t_len_to_receive %d)", cmnd, cmnd->scst_state, + cmnd->on_write_timeout_list, cmnd->write_start, + cmnd->r2t_len_to_receive); + if (cmnd == conn->read_cmnd) { + TRACE_DBG_FLAG(force ? TRACE_CONN_OC_DBG : TRACE_MGMT_DEBUG, + "cmnd %p is read cmd", cmnd); + sBUG_ON(force); + if ((conn->read_state == RX_INIT_BHS) || + (conn->read_state == RX_BHS)) { + TRACE_MGMT_DBG("Unabort not yet received cmnd %p", + cmnd); + clear_bit(ISCSI_CMD_ABORTED, &cmnd->prelim_compl_flags); + } else if (cmnd->scst_state == ISCSI_CMD_STATE_RX_CMD) { + TRACE_MGMT_DBG("Aborted cmnd %p is RX_CMD, " + "keep waiting", cmnd); + goto cont; + } + } + if (((cmnd == conn->read_cmnd) || (cmnd->r2t_len_to_receive != 0)) && (time_after_eq(j, cmnd->write_start + ISCSI_TM_DATA_WAIT_TIMEOUT) || force)) { + if (cmnd == conn->read_cmnd) { + TRACE_MGMT_DBG("Clearing read_cmnd for conn %p", conn); + conn->read_cmnd = NULL; + conn->read_state = RX_INIT_BHS; + } spin_unlock(&conn->write_list_lock); spin_unlock_bh(&conn->conn_thr_pool->rd_lock); iscsi_fail_data_waiting_cmnd(cmnd); goto again; } +cont: aborted_cmds_pending = true; } } diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index 70171503d..9355ebceb 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -2182,15 +2182,16 @@ static void __cmnd_abort(struct iscsi_cmnd *cmnd) "ref_cnt %d, on_write_timeout_list %d, write_start %ld, ITT %x, " "sn %u, op %x, r2t_len_to_receive %d, r2t_len_to_send %d, " "CDB op %x, size to write %u, outstanding_r2t %d, " - "sess->exp_cmd_sn %u, conn %p, rd_task %p)", - cmnd, cmnd->scst_cmd, cmnd->scst_state, + "sess->exp_cmd_sn %u, conn %p, rd_task %p, read_cmnd %p, " + "read_state %d)", cmnd, cmnd->scst_cmd, cmnd->scst_state, atomic_read(&cmnd->ref_cnt), cmnd->on_write_timeout_list, cmnd->write_start, cmnd->pdu.bhs.itt, cmnd->pdu.bhs.sn, cmnd_opcode(cmnd), cmnd->r2t_len_to_receive, cmnd->r2t_len_to_send, cmnd_scsicode(cmnd), cmnd_write_size(cmnd), cmnd->outstanding_r2t, cmnd->conn->session->exp_cmd_sn, cmnd->conn, - cmnd->conn->rd_task); + cmnd->conn->rd_task, cmnd->conn->read_cmnd, + cmnd->conn->read_state); #if defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION) TRACE_MGMT_DBG("net_ref_cnt %d", atomic_read(&cmnd->net_ref_cnt)); diff --git a/iscsi-scst/kernel/iscsi.h b/iscsi-scst/kernel/iscsi.h index ea1527049..6f05f7b37 100644 --- a/iscsi-scst/kernel/iscsi.h +++ b/iscsi-scst/kernel/iscsi.h @@ -326,6 +326,23 @@ struct iscsi_pdu { typedef void (iscsi_show_info_t)(struct seq_file *seq, struct iscsi_target *target); +/* Read data states */ +enum rx_state { + RX_INIT_BHS, /* Must be zero for better "switch" optimization. */ + RX_BHS, + RX_CMD_START, + RX_DATA, + RX_END, + + RX_CMD_CONTINUE, + RX_INIT_HDIGEST, + RX_CHECK_HDIGEST, + RX_INIT_DDIGEST, + RX_CHECK_DDIGEST, + RX_AHS, + RX_PADDING, +}; + /** Commands' states **/ /* New command and SCST processes it */ diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index fdb2d397e..7f0b24636 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -26,22 +26,6 @@ #include "iscsi.h" #include "digest.h" -enum rx_state { - RX_INIT_BHS, /* Must be zero for better "switch" optimization. */ - RX_BHS, - RX_CMD_START, - RX_DATA, - RX_END, - - RX_CMD_CONTINUE, - RX_INIT_HDIGEST, - RX_CHECK_HDIGEST, - RX_INIT_DDIGEST, - RX_CHECK_DDIGEST, - RX_AHS, - RX_PADDING, -}; - enum tx_state { TX_INIT = 0, /* Must be zero for better "switch" optimization. */ TX_BHS_DATA,