From 1f4f117f3f89daee32a816deb8661a18cd5b0b31 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Sat, 9 Nov 2013 03:10:38 +0000 Subject: [PATCH] This patch fixes 2 issues. 1. If we have a nop in flight then we do not really need to send more to test if the other side is still there. Either that nop will timeout and conn will be dropped or it will complete and last_rcv_time will be updated. 2. We are sending nop-ins every nop_in_interval seconds, but if we got a data half way in to the window, then when conn_nop_in_delayed_work_fn is run it was scheduling the next check to be nop_in_interval more seconds. With the current settings this could end up with us waiting 59 secs before sending a nop and about 130 secs for it to timeout, when at 61 it should be timing out and getting cleaned up already. This patch has us take into account when the last time we got data to try and reschedule the next nop check closer to nop_in_interval from that time. Signed-off-by: Mike Christie git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5092 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/conn.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/iscsi-scst/kernel/conn.c b/iscsi-scst/kernel/conn.c index 412f028a0..031f28650 100644 --- a/iscsi-scst/kernel/conn.c +++ b/iscsi-scst/kernel/conn.c @@ -580,19 +580,26 @@ static void conn_nop_in_delayed_work_fn(struct delayed_work *work) struct iscsi_conn *conn = container_of(work, struct iscsi_conn, nop_in_delayed_work); #endif + unsigned long next_timeout = 0; TRACE_ENTRY(); if (time_after_eq(jiffies, conn->last_rcv_time + conn->nop_in_interval)) { - iscsi_send_nop_in(conn); + if (list_empty(&conn->nop_req_list)) + iscsi_send_nop_in(conn); + next_timeout = conn->nop_in_interval; } if ((conn->nop_in_interval > 0) && !test_bit(ISCSI_CONN_SHUTTINGDOWN, &conn->conn_aflags)) { - TRACE_DBG("Reschedule Nop-In work for conn %p", conn); + if (next_timeout == 0) + next_timeout = conn->nop_in_interval - + (jiffies - conn->last_rcv_time); + TRACE_DBG("Reschedule Nop-In work for conn %p in %lu", conn, + next_timeout + ISCSI_ADD_SCHED_TIME); schedule_delayed_work(&conn->nop_in_delayed_work, - conn->nop_in_interval + ISCSI_ADD_SCHED_TIME); + next_timeout + ISCSI_ADD_SCHED_TIME); } TRACE_EXIT();