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.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 212fe2027a8c..c648bd328a21 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1677,6 +1677,22 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
1677 iscsi_conn_queue_work(conn); 1677 iscsi_conn_queue_work(conn);
1678} 1678}
1679 1679
1680/*
1681 * We want to make sure a ping is in flight. It has timed out.
1682 * And we are not busy processing a pdu that is making
1683 * progress but got started before the ping and is taking a while
1684 * to complete so the ping is just stuck behind it in a queue.
1685 */
1686static int iscsi_has_ping_timed_out(struct iscsi_conn *conn)
1687{
1688 if (conn->ping_task &&
1689 time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) +
1690 (conn->ping_timeout * HZ), jiffies))
1691 return 1;
1692 else
1693 return 0;
1694}
1695
1680static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) 1696static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
1681{ 1697{
1682 struct iscsi_cls_session *cls_session; 1698 struct iscsi_cls_session *cls_session;
@@ -1712,16 +1728,20 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
1712 * if the ping timedout then we are in the middle of cleaning up 1728 * if the ping timedout then we are in the middle of cleaning up
1713 * and can let the iscsi eh handle it 1729 * and can let the iscsi eh handle it
1714 */ 1730 */
1715 if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) + 1731 if (iscsi_has_ping_timed_out(conn)) {
1716 (conn->ping_timeout * HZ), jiffies))
1717 rc = BLK_EH_RESET_TIMER; 1732 rc = BLK_EH_RESET_TIMER;
1733 goto done;
1734 }
1718 /* 1735 /*
1719 * if we are about to check the transport then give the command 1736 * if we are about to check the transport then give the command
1720 * more time 1737 * more time
1721 */ 1738 */
1722 if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ), 1739 if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ),
1723 jiffies)) 1740 jiffies)) {
1724 rc = BLK_EH_RESET_TIMER; 1741 rc = BLK_EH_RESET_TIMER;
1742 goto done;
1743 }
1744
1725 /* if in the middle of checking the transport then give us more time */ 1745 /* if in the middle of checking the transport then give us more time */
1726 if (conn->ping_task) 1746 if (conn->ping_task)
1727 rc = BLK_EH_RESET_TIMER; 1747 rc = BLK_EH_RESET_TIMER;
@@ -1748,13 +1768,13 @@ static void iscsi_check_transport_timeouts(unsigned long data)
1748 1768
1749 recv_timeout *= HZ; 1769 recv_timeout *= HZ;
1750 last_recv = conn->last_recv; 1770 last_recv = conn->last_recv;
1751 if (conn->ping_task && 1771
1752 time_before_eq(conn->last_ping + (conn->ping_timeout * HZ), 1772 if (iscsi_has_ping_timed_out(conn)) {
1753 jiffies)) {
1754 iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs " 1773 iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs "
1755 "expired, last rx %lu, last ping %lu, " 1774 "expired, recv timeout %d, last rx %lu, "
1756 "now %lu\n", conn->ping_timeout, last_recv, 1775 "last ping %lu, now %lu\n",
1757 conn->last_ping, jiffies); 1776 conn->ping_timeout, conn->recv_timeout,
1777 last_recv, conn->last_ping, jiffies);
1758 spin_unlock(&session->lock); 1778 spin_unlock(&session->lock);
1759 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); 1779 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
1760 return; 1780 return;