Commit 01a88f7f authored by David Howells's avatar David Howells

rxrpc: Fix call timer

Fix the call timer in the following ways:

 (1) If call->resend_at or call->ack_at are before or equal to the current
     time, then ignore that timeout.

 (2) If call->expire_at is before or equal to the current time, then don't
     set the timer at all (possibly we should queue the call).

 (3) Don't skip modifying the timer if timer_pending() is true.  This
     indicates that the timer is working, not that it has expired and is
     running/waiting to run its expiry handler.

Also call rxrpc_set_timer() to start the call timer going rather than
calling add_timer().
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent be8aa338
...@@ -28,24 +28,27 @@ void rxrpc_set_timer(struct rxrpc_call *call) ...@@ -28,24 +28,27 @@ void rxrpc_set_timer(struct rxrpc_call *call)
{ {
unsigned long t, now = jiffies; unsigned long t, now = jiffies;
_enter("{%ld,%ld,%ld:%ld}",
call->ack_at - now, call->resend_at - now, call->expire_at - now,
call->timer.expires - now);
read_lock_bh(&call->state_lock); read_lock_bh(&call->state_lock);
if (call->state < RXRPC_CALL_COMPLETE) { if (call->state < RXRPC_CALL_COMPLETE) {
t = call->ack_at; t = call->expire_at;
if (time_before(call->resend_at, t)) if (time_before_eq(t, now))
goto out;
if (time_after(call->resend_at, now) &&
time_before(call->resend_at, t))
t = call->resend_at; t = call->resend_at;
if (time_before(call->expire_at, t))
t = call->expire_at; if (time_after(call->ack_at, now) &&
if (!timer_pending(&call->timer) || time_before(call->ack_at, t))
time_before(t, call->timer.expires)) { t = call->ack_at;
_debug("set timer %ld", t - now);
if (call->timer.expires != t || !timer_pending(&call->timer)) {
mod_timer(&call->timer, t); mod_timer(&call->timer, t);
} }
} }
out:
read_unlock_bh(&call->state_lock); read_unlock_bh(&call->state_lock);
} }
......
...@@ -199,8 +199,8 @@ static void rxrpc_start_call_timer(struct rxrpc_call *call) ...@@ -199,8 +199,8 @@ static void rxrpc_start_call_timer(struct rxrpc_call *call)
call->expire_at = expire_at; call->expire_at = expire_at;
call->ack_at = expire_at; call->ack_at = expire_at;
call->resend_at = expire_at; call->resend_at = expire_at;
call->timer.expires = expire_at; call->timer.expires = expire_at + 1;
add_timer(&call->timer); rxrpc_set_timer(call);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment