summaryrefslogtreecommitdiff
path: root/net/rxrpc/call_event.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-08-23 17:27:25 +0300
committerDavid Howells <dhowells@redhat.com>2016-08-23 18:02:35 +0300
commit563ea7d5d4eaf0ff63ddcaf8ed849eb88bb5738d (patch)
tree0a440b2f02e5a16d30058aa8b0f8fb10e8584b35 /net/rxrpc/call_event.c
parentf51b4480021c470d1f5e8066ccc7c10513bd4e37 (diff)
downloadlinux-563ea7d5d4eaf0ff63ddcaf8ed849eb88bb5738d.tar.xz
rxrpc: Calculate serial skew on packet reception
Calculate the serial number skew in the data_ready handler when a packet has been received and a connection looked up. The skew is cached in the sk_buff's priority field. The connection highest received serial number is updated at this time also. This can be done without locks or atomic instructions because, at this point, the code is serialised by the socket. This generates more accurate skew data because if the packet is offloaded to a work queue before this is determined, more packets may come in, bumping the highest serial number and thereby increasing the apparent skew. This also removes some unnecessary atomic ops. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net/rxrpc/call_event.c')
-rw-r--r--net/rxrpc/call_event.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c
index 3d1267cea9ea..3d1961d82325 100644
--- a/net/rxrpc/call_event.c
+++ b/net/rxrpc/call_event.c
@@ -25,7 +25,7 @@
* propose an ACK be sent
*/
void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
- u32 serial, bool immediate)
+ u16 skew, u32 serial, bool immediate)
{
unsigned long expiry;
s8 prior = rxrpc_ack_priority[ack_reason];
@@ -44,8 +44,10 @@ void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
/* update DELAY, IDLE, REQUESTED and PING_RESPONSE ACK serial
* numbers */
if (prior == rxrpc_ack_priority[call->ackr_reason]) {
- if (prior <= 4)
+ if (prior <= 4) {
+ call->ackr_skew = skew;
call->ackr_serial = serial;
+ }
if (immediate)
goto cancel_timer;
return;
@@ -103,13 +105,13 @@ cancel_timer:
* propose an ACK be sent, locking the call structure
*/
void rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
- u32 serial, bool immediate)
+ u16 skew, u32 serial, bool immediate)
{
s8 prior = rxrpc_ack_priority[ack_reason];
if (prior > rxrpc_ack_priority[call->ackr_reason]) {
spin_lock_bh(&call->lock);
- __rxrpc_propose_ACK(call, ack_reason, serial, immediate);
+ __rxrpc_propose_ACK(call, ack_reason, skew, serial, immediate);
spin_unlock_bh(&call->lock);
}
}
@@ -628,7 +630,7 @@ process_further:
if (ack.reason == RXRPC_ACK_PING) {
_proto("Rx ACK %%%u PING Request", latest);
rxrpc_propose_ACK(call, RXRPC_ACK_PING_RESPONSE,
- sp->hdr.serial, true);
+ skb->priority, sp->hdr.serial, true);
}
/* discard any out-of-order or duplicate ACKs */
@@ -1153,8 +1155,7 @@ skip_msg_init:
goto maybe_reschedule;
send_ACK_with_skew:
- ack.maxSkew = htons(atomic_read(&call->conn->hi_serial) -
- ntohl(ack.serial));
+ ack.maxSkew = htons(call->ackr_skew);
send_ACK:
mtu = call->conn->params.peer->if_mtu;
mtu -= call->conn->params.peer->hdrsize;
@@ -1244,7 +1245,8 @@ send_message_2:
case RXRPC_CALL_SERVER_ACK_REQUEST:
_debug("start ACK timer");
rxrpc_propose_ACK(call, RXRPC_ACK_DELAY,
- call->ackr_serial, false);
+ call->ackr_skew, call->ackr_serial,
+ false);
default:
break;
}