From c54ebba11a0b7fe41783988fb553af799b3118d5 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Wed, 18 May 2011 21:45:09 +0000 Subject: [PATCH] Some more TM cleanups/improvements git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3460 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/conn.c | 54 ++++++++++++++++++------------------- iscsi-scst/kernel/iscsi.h | 26 ++++++------------ iscsi-scst/kernel/nthread.c | 17 ++++++++++++ 3 files changed, 51 insertions(+), 46 deletions(-) diff --git a/iscsi-scst/kernel/conn.c b/iscsi-scst/kernel/conn.c index 445c74a23..990cc8851 100644 --- a/iscsi-scst/kernel/conn.c +++ b/iscsi-scst/kernel/conn.c @@ -634,39 +634,37 @@ again: aborted_cmds_pending = false; list_for_each_entry(cmnd, &conn->write_timeout_list, write_timeout_list_entry) { + /* + * This should not happen, because DATA OUT commands can't get + * into write_timeout_list. + */ + sBUG_ON(cmnd->cmd_req != NULL); + if (test_bit(ISCSI_CMD_ABORTED, &cmnd->prelim_compl_flags)) { - TRACE_DBG_FLAG(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 == conn->read_cmnd) { - TRACE_DBG_FLAG(TRACE_MGMT_DEBUG, - "cmnd %p is read cmd", cmnd); - sBUG_ON(force); - sBUG_ON((conn->read_state == RX_INIT_BHS) || - (conn->read_state == RX_BHS)); - 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->data_out_in_data_receiving) { - TRACE_MGMT_DBG("Aborted cmnd %p is waiting for " - "DATA OUT data, keep waiting", cmnd); + TRACE_MGMT_DBG("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 == conn->read_cmnd) || + cmnd->data_out_in_data_receiving) { + sBUG_ON((cmnd == conn->read_cmnd) && force); + /* + * We can't abort command waiting for data from + * the net, because otherwise we are risking to + * get out of sync with the sender, so we have + * to wait until the timeout timer gets into the + * action and close this connection. + */ + TRACE_MGMT_DBG("Aborted cmnd %p is %s, " + "keep waiting", cmnd, + (cmnd == conn->read_cmnd) ? "RX cmnd" : + "waiting for DATA OUT data"); goto cont; } - if (((cmnd == conn->read_cmnd) || (cmnd->r2t_len_to_receive != 0)) && + if ((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); diff --git a/iscsi-scst/kernel/iscsi.h b/iscsi-scst/kernel/iscsi.h index c61913835..fdfb307bd 100644 --- a/iscsi-scst/kernel/iscsi.h +++ b/iscsi-scst/kernel/iscsi.h @@ -326,23 +326,6 @@ 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 */ @@ -778,8 +761,15 @@ static inline void cmd_del_from_rx_ddigest_list(struct iscsi_cmnd *cmnd) static inline unsigned long iscsi_get_timeout(struct iscsi_cmnd *req) { - return (cmnd_opcode(req) == ISCSI_OP_NOP_OUT) ? + unsigned long res; + + res = (cmnd_opcode(req) == ISCSI_OP_NOP_OUT) ? req->conn->nop_in_timeout : req->conn->data_rsp_timeout; + + if (unlikely(test_bit(ISCSI_CMD_ABORTED, &req->prelim_compl_flags))) + res = min_t(unsigned long, res, ISCSI_TM_DATA_WAIT_TIMEOUT); + + return res; } static inline unsigned long iscsi_get_timeout_time(struct iscsi_cmnd *req) diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index c0935ad9a..8c316bdcd 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -25,6 +25,23 @@ #include "iscsi.h" #include "digest.h" +/* 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, +}; + enum tx_state { TX_INIT = 0, /* Must be zero for better "switch" optimization. */ TX_BHS_DATA,