Skip to content

Commit

Permalink
rxrpc: Fix missing start of call timeout
Browse files Browse the repository at this point in the history
The expect_rx_by call timeout is supposed to be set when a call is started
to indicate that we need to receive a packet by that point.  This is
currently put back every time we receive a packet, but it isn't started
when we first send a packet.  Without this, the call may wait forever if
the server doesn't deign to reply.

Fix this by setting the timeout upon a successful UDP sendmsg call for the
first DATA packet.  The timeout is initiated only for initial transmission
and not for subsequent retries as we don't want the retry mechanism to
extend the timeout indefinitely.

Fixes: a158bdd ("rxrpc: Fix call timeouts")
Reported-by: Marc Dionne <marc.dionne@auristor.com>
Signed-off-by: David Howells <dhowells@redhat.com>
  • Loading branch information
David Howells committed May 10, 2018
1 parent 4a026da commit c54e43d
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 1 deletion.
1 change: 1 addition & 0 deletions net/rxrpc/ar-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ enum rxrpc_call_flag {
RXRPC_CALL_SEND_PING, /* A ping will need to be sent */
RXRPC_CALL_PINGING, /* Ping in process */
RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */
RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */
};

/*
Expand Down
2 changes: 1 addition & 1 deletion net/rxrpc/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -971,7 +971,7 @@ static void rxrpc_input_call_packet(struct rxrpc_call *call,
if (timo) {
unsigned long now = jiffies, expect_rx_by;

expect_rx_by = jiffies + timo;
expect_rx_by = now + timo;
WRITE_ONCE(call->expect_rx_by, expect_rx_by);
rxrpc_reduce_call_timer(call, expect_rx_by, now,
rxrpc_timer_set_for_normal);
Expand Down
11 changes: 11 additions & 0 deletions net/rxrpc/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,17 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
rxrpc_timer_set_for_lost_ack);
}
}

if (sp->hdr.seq == 1 &&
!test_and_set_bit(RXRPC_CALL_BEGAN_RX_TIMER,
&call->flags)) {
unsigned long nowj = jiffies, expect_rx_by;

expect_rx_by = nowj + call->next_rx_timo;
WRITE_ONCE(call->expect_rx_by, expect_rx_by);
rxrpc_reduce_call_timer(call, expect_rx_by, nowj,
rxrpc_timer_set_for_normal);
}
}

rxrpc_set_keepalive(call);
Expand Down
10 changes: 10 additions & 0 deletions net/rxrpc/sendmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,15 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,

ret = rxrpc_send_data_packet(call, skb, false);
if (ret < 0) {
switch (ret) {
case -ENETUNREACH:
case -EHOSTUNREACH:
case -ECONNREFUSED:
rxrpc_set_call_completion(call,
RXRPC_CALL_LOCAL_ERROR,
0, ret);
goto out;
}
_debug("need instant resend %d", ret);
rxrpc_instant_resend(call, ix);
} else {
Expand All @@ -241,6 +250,7 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
rxrpc_timer_set_for_send);
}

out:
rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
_leave("");
}
Expand Down

0 comments on commit c54e43d

Please sign in to comment.