summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c47
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 4d85ce10019..5606d1e6297 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -596,9 +596,16 @@ static void iscsi_prep_mtask(struct iscsi_conn *conn,
nop->cmdsn = cpu_to_be32(session->cmdsn);
if (hdr->itt != RESERVED_ITT) {
hdr->itt = build_itt(mtask->itt, conn->id, session->age);
+ /*
+ * TODO: We always use immediate, so we never hit this.
+ * If we start to send tmfs or nops as non-immediate then
+ * we should start checking the cmdsn numbers for mgmt tasks.
+ */
if (conn->c_stage == ISCSI_CONN_STARTED &&
- !(hdr->opcode & ISCSI_OP_IMMEDIATE))
+ !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
+ session->queued_cmdsn++;
session->cmdsn++;
+ }
}
if (session->tt->init_mgmt_task)
@@ -641,9 +648,11 @@ static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn)
/*
* Check for iSCSI window and take care of CmdSN wrap-around
*/
- if (!iscsi_sna_lte(session->cmdsn, session->max_cmdsn)) {
- debug_scsi("iSCSI CmdSN closed. MaxCmdSN %u CmdSN %u\n",
- session->max_cmdsn, session->cmdsn);
+ if (!iscsi_sna_lte(session->queued_cmdsn, session->max_cmdsn)) {
+ debug_scsi("iSCSI CmdSN closed. ExpCmdSn %u MaxCmdSN %u "
+ "CmdSN %u/%u\n", session->exp_cmdsn,
+ session->max_cmdsn, session->cmdsn,
+ session->queued_cmdsn);
return -ENOSPC;
}
return 0;
@@ -722,11 +731,6 @@ check_mgmt:
/* process command queue */
while (!list_empty(&conn->xmitqueue)) {
- rc = iscsi_check_cmdsn_window_closed(conn);
- if (rc) {
- spin_unlock_bh(&conn->session->lock);
- return rc;
- }
/*
* iscsi tcp may readd the task to the xmitqueue to send
* write data
@@ -834,12 +838,6 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
goto fault;
}
- /*
- * We check this here and in data xmit, because if we get to the point
- * that this check is hitting the window then we have enough IO in
- * flight and enough IO waiting to be transmitted it is better
- * to let the scsi/block layer queue up.
- */
if (iscsi_check_cmdsn_window_closed(conn)) {
reason = FAILURE_WINDOW_CLOSED;
goto reject;
@@ -850,6 +848,8 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
reason = FAILURE_OOM;
goto reject;
}
+ session->queued_cmdsn++;
+
sc->SCp.phase = session->age;
sc->SCp.ptr = (char *)ctask;
@@ -1140,7 +1140,13 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
if (!sc)
return;
- if (ctask->state != ISCSI_TASK_PENDING)
+ if (ctask->state == ISCSI_TASK_PENDING)
+ /*
+ * cmd never made it to the xmit thread, so we should not count
+ * the cmd in the sequencing
+ */
+ conn->session->queued_cmdsn--;
+ else
conn->session->tt->cleanup_cmd_task(conn, ctask);
iscsi_ctask_mtask_cleanup(ctask);
@@ -1392,7 +1398,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
session->state = ISCSI_STATE_FREE;
session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
session->cmds_max = cmds_max;
- session->cmdsn = initial_cmdsn;
+ session->queued_cmdsn = session->cmdsn = initial_cmdsn;
session->exp_cmdsn = initial_cmdsn + 1;
session->max_cmdsn = initial_cmdsn + 1;
session->max_r2t = 1;
@@ -1473,6 +1479,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
struct module *owner = cls_session->transport->owner;
+ iscsi_unblock_session(cls_session);
scsi_remove_host(shost);
iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
@@ -1615,11 +1622,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
kfree(conn->persistent_address);
__kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
sizeof(void*));
- if (session->leadconn == conn) {
+ if (session->leadconn == conn)
session->leadconn = NULL;
- /* no connections exits.. reset sequencing */
- session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1;
- }
spin_unlock_bh(&session->lock);
kfifo_free(conn->mgmtqueue);
@@ -1649,6 +1653,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
spin_lock_bh(&session->lock);
conn->c_stage = ISCSI_CONN_STARTED;
session->state = ISCSI_STATE_LOGGED_IN;
+ session->queued_cmdsn = session->cmdsn;
switch(conn->stop_stage) {
case STOP_CONN_RECOVER: