aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/libiscsi.c62
-rw-r--r--drivers/scsi/libiscsi_tcp.c6
2 files changed, 53 insertions, 15 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 59908aead531..b55b7991d5fa 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -954,6 +954,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
954 task = iscsi_itt_to_ctask(conn, hdr->itt); 954 task = iscsi_itt_to_ctask(conn, hdr->itt);
955 if (!task) 955 if (!task)
956 return ISCSI_ERR_BAD_ITT; 956 return ISCSI_ERR_BAD_ITT;
957 task->last_xfer = jiffies;
957 break; 958 break;
958 case ISCSI_OP_R2T: 959 case ISCSI_OP_R2T:
959 /* 960 /*
@@ -1192,10 +1193,12 @@ static int iscsi_xmit_task(struct iscsi_conn *conn)
1192 spin_unlock_bh(&conn->session->lock); 1193 spin_unlock_bh(&conn->session->lock);
1193 rc = conn->session->tt->xmit_task(task); 1194 rc = conn->session->tt->xmit_task(task);
1194 spin_lock_bh(&conn->session->lock); 1195 spin_lock_bh(&conn->session->lock);
1195 __iscsi_put_task(task); 1196 if (!rc) {
1196 if (!rc)
1197 /* done with this task */ 1197 /* done with this task */
1198 task->last_xfer = jiffies;
1198 conn->task = NULL; 1199 conn->task = NULL;
1200 }
1201 __iscsi_put_task(task);
1199 return rc; 1202 return rc;
1200} 1203}
1201 1204
@@ -1361,6 +1364,9 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn,
1361 task->state = ISCSI_TASK_PENDING; 1364 task->state = ISCSI_TASK_PENDING;
1362 task->conn = conn; 1365 task->conn = conn;
1363 task->sc = sc; 1366 task->sc = sc;
1367 task->have_checked_conn = false;
1368 task->last_timeout = jiffies;
1369 task->last_xfer = jiffies;
1364 INIT_LIST_HEAD(&task->running); 1370 INIT_LIST_HEAD(&task->running);
1365 return task; 1371 return task;
1366} 1372}
@@ -1716,17 +1722,18 @@ static int iscsi_has_ping_timed_out(struct iscsi_conn *conn)
1716 return 0; 1722 return 0;
1717} 1723}
1718 1724
1719static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) 1725static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
1720{ 1726{
1727 enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
1728 struct iscsi_task *task = NULL;
1721 struct iscsi_cls_session *cls_session; 1729 struct iscsi_cls_session *cls_session;
1722 struct iscsi_session *session; 1730 struct iscsi_session *session;
1723 struct iscsi_conn *conn; 1731 struct iscsi_conn *conn;
1724 enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
1725 1732
1726 cls_session = starget_to_session(scsi_target(scmd->device)); 1733 cls_session = starget_to_session(scsi_target(sc->device));
1727 session = cls_session->dd_data; 1734 session = cls_session->dd_data;
1728 1735
1729 ISCSI_DBG_SESSION(session, "scsi cmd %p timedout\n", scmd); 1736 ISCSI_DBG_SESSION(session, "scsi cmd %p timedout\n", sc);
1730 1737
1731 spin_lock(&session->lock); 1738 spin_lock(&session->lock);
1732 if (session->state != ISCSI_STATE_LOGGED_IN) { 1739 if (session->state != ISCSI_STATE_LOGGED_IN) {
@@ -1745,6 +1752,26 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
1745 goto done; 1752 goto done;
1746 } 1753 }
1747 1754
1755 task = (struct iscsi_task *)sc->SCp.ptr;
1756 if (!task)
1757 goto done;
1758 /*
1759 * If we have sent (at least queued to the network layer) a pdu or
1760 * recvd one for the task since the last timeout ask for
1761 * more time. If on the next timeout we have not made progress
1762 * we can check if it is the task or connection when we send the
1763 * nop as a ping.
1764 */
1765 if (time_after_eq(task->last_xfer, task->last_timeout)) {
1766 ISCSI_DBG_CONN(conn, "Command making progress. Asking "
1767 "scsi-ml for more time to complete. "
1768 "Last data recv at %lu. Last timeout was at "
1769 "%lu\n.", task->last_xfer, task->last_timeout);
1770 task->have_checked_conn = false;
1771 rc = BLK_EH_RESET_TIMER;
1772 goto done;
1773 }
1774
1748 if (!conn->recv_timeout && !conn->ping_timeout) 1775 if (!conn->recv_timeout && !conn->ping_timeout)
1749 goto done; 1776 goto done;
1750 /* 1777 /*
@@ -1755,20 +1782,29 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
1755 rc = BLK_EH_RESET_TIMER; 1782 rc = BLK_EH_RESET_TIMER;
1756 goto done; 1783 goto done;
1757 } 1784 }
1785
1786 /* Assumes nop timeout is shorter than scsi cmd timeout */
1787 if (task->have_checked_conn)
1788 goto done;
1789
1758 /* 1790 /*
1759 * if we are about to check the transport then give the command 1791 * Checking the transport already or nop from a cmd timeout still
1760 * more time 1792 * running
1761 */ 1793 */
1762 if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ), 1794 if (conn->ping_task) {
1763 jiffies)) { 1795 task->have_checked_conn = true;
1764 rc = BLK_EH_RESET_TIMER; 1796 rc = BLK_EH_RESET_TIMER;
1765 goto done; 1797 goto done;
1766 } 1798 }
1767 1799
1768 /* if in the middle of checking the transport then give us more time */ 1800 /* Make sure there is a transport check done */
1769 if (conn->ping_task) 1801 iscsi_send_nopout(conn, NULL);
1770 rc = BLK_EH_RESET_TIMER; 1802 task->have_checked_conn = true;
1803 rc = BLK_EH_RESET_TIMER;
1804
1771done: 1805done:
1806 if (task)
1807 task->last_timeout = jiffies;
1772 spin_unlock(&session->lock); 1808 spin_unlock(&session->lock);
1773 ISCSI_DBG_SESSION(session, "return %s\n", rc == BLK_EH_RESET_TIMER ? 1809 ISCSI_DBG_SESSION(session, "return %s\n", rc == BLK_EH_RESET_TIMER ?
1774 "timer reset" : "nh"); 1810 "timer reset" : "nh");
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index 2bc07090321d..2e0746d70303 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -686,6 +686,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
686 "offset=%d, datalen=%d)\n", 686 "offset=%d, datalen=%d)\n",
687 tcp_task->data_offset, 687 tcp_task->data_offset,
688 tcp_conn->in.datalen); 688 tcp_conn->in.datalen);
689 task->last_xfer = jiffies;
689 rc = iscsi_segment_seek_sg(&tcp_conn->in.segment, 690 rc = iscsi_segment_seek_sg(&tcp_conn->in.segment,
690 sdb->table.sgl, 691 sdb->table.sgl,
691 sdb->table.nents, 692 sdb->table.nents,
@@ -713,9 +714,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
713 rc = ISCSI_ERR_BAD_ITT; 714 rc = ISCSI_ERR_BAD_ITT;
714 else if (ahslen) 715 else if (ahslen)
715 rc = ISCSI_ERR_AHSLEN; 716 rc = ISCSI_ERR_AHSLEN;
716 else if (task->sc->sc_data_direction == DMA_TO_DEVICE) 717 else if (task->sc->sc_data_direction == DMA_TO_DEVICE) {
718 task->last_xfer = jiffies;
717 rc = iscsi_tcp_r2t_rsp(conn, task); 719 rc = iscsi_tcp_r2t_rsp(conn, task);
718 else 720 } else
719 rc = ISCSI_ERR_PROTO; 721 rc = ISCSI_ERR_PROTO;
720 spin_unlock(&conn->session->lock); 722 spin_unlock(&conn->session->lock);
721 break; 723 break;