aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2007-07-26 13:46:48 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-07-27 09:12:05 -0400
commite07264071f7f2b02a2973cb28d9fdf5eb8866cc1 (patch)
tree25ca60eeb25dbb519428d3e4bbea77d978e5a4a1
parent7974392c0b0d4e7a2a17ca3597d51a29b9841aa5 (diff)
[SCSI] libiscsi: fix cmd seqeunce number checking
We should not be checking the cmd windown for just handling r2t responses. And if the window closes in on us, always have scsi-ml requeue the command from our queuecommand function. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/libiscsi.c46
-rw-r--r--include/scsi/libiscsi.h3
2 files changed, 28 insertions, 21 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 271a2d671b89..5606d1e62978 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -596,9 +596,16 @@ static void iscsi_prep_mtask(struct iscsi_conn *conn,
596 nop->cmdsn = cpu_to_be32(session->cmdsn); 596 nop->cmdsn = cpu_to_be32(session->cmdsn);
597 if (hdr->itt != RESERVED_ITT) { 597 if (hdr->itt != RESERVED_ITT) {
598 hdr->itt = build_itt(mtask->itt, conn->id, session->age); 598 hdr->itt = build_itt(mtask->itt, conn->id, session->age);
599 /*
600 * TODO: We always use immediate, so we never hit this.
601 * If we start to send tmfs or nops as non-immediate then
602 * we should start checking the cmdsn numbers for mgmt tasks.
603 */
599 if (conn->c_stage == ISCSI_CONN_STARTED && 604 if (conn->c_stage == ISCSI_CONN_STARTED &&
600 !(hdr->opcode & ISCSI_OP_IMMEDIATE)) 605 !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
606 session->queued_cmdsn++;
601 session->cmdsn++; 607 session->cmdsn++;
608 }
602 } 609 }
603 610
604 if (session->tt->init_mgmt_task) 611 if (session->tt->init_mgmt_task)
@@ -641,9 +648,11 @@ static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn)
641 /* 648 /*
642 * Check for iSCSI window and take care of CmdSN wrap-around 649 * Check for iSCSI window and take care of CmdSN wrap-around
643 */ 650 */
644 if (!iscsi_sna_lte(session->cmdsn, session->max_cmdsn)) { 651 if (!iscsi_sna_lte(session->queued_cmdsn, session->max_cmdsn)) {
645 debug_scsi("iSCSI CmdSN closed. MaxCmdSN %u CmdSN %u\n", 652 debug_scsi("iSCSI CmdSN closed. ExpCmdSn %u MaxCmdSN %u "
646 session->max_cmdsn, session->cmdsn); 653 "CmdSN %u/%u\n", session->exp_cmdsn,
654 session->max_cmdsn, session->cmdsn,
655 session->queued_cmdsn);
647 return -ENOSPC; 656 return -ENOSPC;
648 } 657 }
649 return 0; 658 return 0;
@@ -722,11 +731,6 @@ check_mgmt:
722 731
723 /* process command queue */ 732 /* process command queue */
724 while (!list_empty(&conn->xmitqueue)) { 733 while (!list_empty(&conn->xmitqueue)) {
725 rc = iscsi_check_cmdsn_window_closed(conn);
726 if (rc) {
727 spin_unlock_bh(&conn->session->lock);
728 return rc;
729 }
730 /* 734 /*
731 * iscsi tcp may readd the task to the xmitqueue to send 735 * iscsi tcp may readd the task to the xmitqueue to send
732 * write data 736 * write data
@@ -834,12 +838,6 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
834 goto fault; 838 goto fault;
835 } 839 }
836 840
837 /*
838 * We check this here and in data xmit, because if we get to the point
839 * that this check is hitting the window then we have enough IO in
840 * flight and enough IO waiting to be transmitted it is better
841 * to let the scsi/block layer queue up.
842 */
843 if (iscsi_check_cmdsn_window_closed(conn)) { 841 if (iscsi_check_cmdsn_window_closed(conn)) {
844 reason = FAILURE_WINDOW_CLOSED; 842 reason = FAILURE_WINDOW_CLOSED;
845 goto reject; 843 goto reject;
@@ -850,6 +848,8 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
850 reason = FAILURE_OOM; 848 reason = FAILURE_OOM;
851 goto reject; 849 goto reject;
852 } 850 }
851 session->queued_cmdsn++;
852
853 sc->SCp.phase = session->age; 853 sc->SCp.phase = session->age;
854 sc->SCp.ptr = (char *)ctask; 854 sc->SCp.ptr = (char *)ctask;
855 855
@@ -1140,7 +1140,13 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1140 if (!sc) 1140 if (!sc)
1141 return; 1141 return;
1142 1142
1143 if (ctask->state != ISCSI_TASK_PENDING) 1143 if (ctask->state == ISCSI_TASK_PENDING)
1144 /*
1145 * cmd never made it to the xmit thread, so we should not count
1146 * the cmd in the sequencing
1147 */
1148 conn->session->queued_cmdsn--;
1149 else
1144 conn->session->tt->cleanup_cmd_task(conn, ctask); 1150 conn->session->tt->cleanup_cmd_task(conn, ctask);
1145 iscsi_ctask_mtask_cleanup(ctask); 1151 iscsi_ctask_mtask_cleanup(ctask);
1146 1152
@@ -1392,7 +1398,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
1392 session->state = ISCSI_STATE_FREE; 1398 session->state = ISCSI_STATE_FREE;
1393 session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; 1399 session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
1394 session->cmds_max = cmds_max; 1400 session->cmds_max = cmds_max;
1395 session->cmdsn = initial_cmdsn; 1401 session->queued_cmdsn = session->cmdsn = initial_cmdsn;
1396 session->exp_cmdsn = initial_cmdsn + 1; 1402 session->exp_cmdsn = initial_cmdsn + 1;
1397 session->max_cmdsn = initial_cmdsn + 1; 1403 session->max_cmdsn = initial_cmdsn + 1;
1398 session->max_r2t = 1; 1404 session->max_r2t = 1;
@@ -1616,11 +1622,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
1616 kfree(conn->persistent_address); 1622 kfree(conn->persistent_address);
1617 __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, 1623 __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
1618 sizeof(void*)); 1624 sizeof(void*));
1619 if (session->leadconn == conn) { 1625 if (session->leadconn == conn)
1620 session->leadconn = NULL; 1626 session->leadconn = NULL;
1621 /* no connections exits.. reset sequencing */
1622 session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1;
1623 }
1624 spin_unlock_bh(&session->lock); 1627 spin_unlock_bh(&session->lock);
1625 1628
1626 kfifo_free(conn->mgmtqueue); 1629 kfifo_free(conn->mgmtqueue);
@@ -1650,6 +1653,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
1650 spin_lock_bh(&session->lock); 1653 spin_lock_bh(&session->lock);
1651 conn->c_stage = ISCSI_CONN_STARTED; 1654 conn->c_stage = ISCSI_CONN_STARTED;
1652 session->state = ISCSI_STATE_LOGGED_IN; 1655 session->state = ISCSI_STATE_LOGGED_IN;
1656 session->queued_cmdsn = session->cmdsn;
1653 1657
1654 switch(conn->stop_stage) { 1658 switch(conn->stop_stage) {
1655 case STOP_CONN_RECOVER: 1659 case STOP_CONN_RECOVER:
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 3f631b08a1ab..007d442412e2 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -210,6 +210,9 @@ struct iscsi_session {
210 uint32_t exp_cmdsn; 210 uint32_t exp_cmdsn;
211 uint32_t max_cmdsn; 211 uint32_t max_cmdsn;
212 212
213 /* This tracks the reqs queued into the initiator */
214 uint32_t queued_cmdsn;
215
213 /* configuration */ 216 /* configuration */
214 int initial_r2t_en; 217 int initial_r2t_en;
215 unsigned max_r2t; 218 unsigned max_r2t;