aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c53
1 files changed, 49 insertions, 4 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index c28a712fd4db..703eb6a88790 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1919,10 +1919,11 @@ static int iscsi_has_ping_timed_out(struct iscsi_conn *conn)
1919static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) 1919static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
1920{ 1920{
1921 enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED; 1921 enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
1922 struct iscsi_task *task = NULL; 1922 struct iscsi_task *task = NULL, *running_task;
1923 struct iscsi_cls_session *cls_session; 1923 struct iscsi_cls_session *cls_session;
1924 struct iscsi_session *session; 1924 struct iscsi_session *session;
1925 struct iscsi_conn *conn; 1925 struct iscsi_conn *conn;
1926 int i;
1926 1927
1927 cls_session = starget_to_session(scsi_target(sc->device)); 1928 cls_session = starget_to_session(scsi_target(sc->device));
1928 session = cls_session->dd_data; 1929 session = cls_session->dd_data;
@@ -1947,8 +1948,15 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
1947 } 1948 }
1948 1949
1949 task = (struct iscsi_task *)sc->SCp.ptr; 1950 task = (struct iscsi_task *)sc->SCp.ptr;
1950 if (!task) 1951 if (!task) {
1952 /*
1953 * Raced with completion. Just reset timer, and let it
1954 * complete normally
1955 */
1956 rc = BLK_EH_RESET_TIMER;
1951 goto done; 1957 goto done;
1958 }
1959
1952 /* 1960 /*
1953 * If we have sent (at least queued to the network layer) a pdu or 1961 * If we have sent (at least queued to the network layer) a pdu or
1954 * recvd one for the task since the last timeout ask for 1962 * recvd one for the task since the last timeout ask for
@@ -1956,10 +1964,10 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
1956 * we can check if it is the task or connection when we send the 1964 * we can check if it is the task or connection when we send the
1957 * nop as a ping. 1965 * nop as a ping.
1958 */ 1966 */
1959 if (time_after_eq(task->last_xfer, task->last_timeout)) { 1967 if (time_after(task->last_xfer, task->last_timeout)) {
1960 ISCSI_DBG_EH(session, "Command making progress. Asking " 1968 ISCSI_DBG_EH(session, "Command making progress. Asking "
1961 "scsi-ml for more time to complete. " 1969 "scsi-ml for more time to complete. "
1962 "Last data recv at %lu. Last timeout was at " 1970 "Last data xfer at %lu. Last timeout was at "
1963 "%lu\n.", task->last_xfer, task->last_timeout); 1971 "%lu\n.", task->last_xfer, task->last_timeout);
1964 task->have_checked_conn = false; 1972 task->have_checked_conn = false;
1965 rc = BLK_EH_RESET_TIMER; 1973 rc = BLK_EH_RESET_TIMER;
@@ -1977,6 +1985,43 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
1977 goto done; 1985 goto done;
1978 } 1986 }
1979 1987
1988 for (i = 0; i < conn->session->cmds_max; i++) {
1989 running_task = conn->session->cmds[i];
1990 if (!running_task->sc || running_task == task ||
1991 running_task->state != ISCSI_TASK_RUNNING)
1992 continue;
1993
1994 /*
1995 * Only check if cmds started before this one have made
1996 * progress, or this could never fail
1997 */
1998 if (time_after(running_task->sc->jiffies_at_alloc,
1999 task->sc->jiffies_at_alloc))
2000 continue;
2001
2002 if (time_after(running_task->last_xfer, task->last_timeout)) {
2003 /*
2004 * This task has not made progress, but a task
2005 * started before us has transferred data since
2006 * we started/last-checked. We could be queueing
2007 * too many tasks or the LU is bad.
2008 *
2009 * If the device is bad the cmds ahead of us on
2010 * other devs will complete, and this loop will
2011 * eventually fail starting the scsi eh.
2012 */
2013 ISCSI_DBG_EH(session, "Command has not made progress "
2014 "but commands ahead of it have. "
2015 "Asking scsi-ml for more time to "
2016 "complete. Our last xfer vs running task "
2017 "last xfer %lu/%lu. Last check %lu.\n",
2018 task->last_xfer, running_task->last_xfer,
2019 task->last_timeout);
2020 rc = BLK_EH_RESET_TIMER;
2021 goto done;
2022 }
2023 }
2024
1980 /* Assumes nop timeout is shorter than scsi cmd timeout */ 2025 /* Assumes nop timeout is shorter than scsi cmd timeout */
1981 if (task->have_checked_conn) 2026 if (task->have_checked_conn)
1982 goto done; 2027 goto done;