lkml.org 
[lkml]   [2022]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 252/452] rxrpc: Fix overlapping ACK accounting
    Date
    From: David Howells <dhowells@redhat.com>

    [ Upstream commit 8940ba3cfe4841928777fd45eaa92051522c7f0c ]

    Fix accidental overlapping of Rx-phase ACK accounting with Tx-phase ACK
    accounting through variables shared between the two. call->acks_* members
    refer to ACKs received in the Tx phase and call->ackr_* members to ACKs
    sent/to be sent during the Rx phase.

    Fixes: 1a2391c30c0b ("rxrpc: Fix detection of out of order acks")
    Signed-off-by: David Howells <dhowells@redhat.com>
    cc: Jeffrey Altman <jaltman@auristor.com>
    cc: Marc Dionne <marc.dionne@auristor.com>
    cc: linux-afs@lists.infradead.org
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/rxrpc/ar-internal.h | 7 ++++---
    net/rxrpc/input.c | 16 ++++++++--------
    2 files changed, 12 insertions(+), 11 deletions(-)

    diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
    index 3bad9f5f9102..2fc93467780d 100644
    --- a/net/rxrpc/ar-internal.h
    +++ b/net/rxrpc/ar-internal.h
    @@ -659,10 +659,9 @@ struct rxrpc_call {

    spinlock_t input_lock; /* Lock for packet input to this call */

    - /* receive-phase ACK management */
    + /* Receive-phase ACK management (ACKs we send). */
    u8 ackr_reason; /* reason to ACK */
    rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */
    - rxrpc_serial_t ackr_first_seq; /* first sequence number received */
    rxrpc_seq_t ackr_prev_seq; /* previous sequence number received */
    rxrpc_seq_t ackr_consumed; /* Highest packet shown consumed */
    rxrpc_seq_t ackr_seen; /* Highest packet shown seen */
    @@ -675,8 +674,10 @@ struct rxrpc_call {
    #define RXRPC_CALL_RTT_AVAIL_MASK 0xf
    #define RXRPC_CALL_RTT_PEND_SHIFT 8

    - /* transmission-phase ACK management */
    + /* Transmission-phase ACK management (ACKs we've received). */
    ktime_t acks_latest_ts; /* Timestamp of latest ACK received */
    + rxrpc_seq_t acks_first_seq; /* first sequence number received */
    + rxrpc_seq_t acks_prev_seq; /* previous sequence number received */
    rxrpc_seq_t acks_lowest_nak; /* Lowest NACK in the buffer (or ==tx_hard_ack) */
    rxrpc_seq_t acks_lost_top; /* tx_top at the time lost-ack ping sent */
    rxrpc_serial_t acks_lost_ping; /* Serial number of probe ACK */
    diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
    index dc201363f2c4..f11673cda217 100644
    --- a/net/rxrpc/input.c
    +++ b/net/rxrpc/input.c
    @@ -812,7 +812,7 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call, u8 *acks,
    static bool rxrpc_is_ack_valid(struct rxrpc_call *call,
    rxrpc_seq_t first_pkt, rxrpc_seq_t prev_pkt)
    {
    - rxrpc_seq_t base = READ_ONCE(call->ackr_first_seq);
    + rxrpc_seq_t base = READ_ONCE(call->acks_first_seq);

    if (after(first_pkt, base))
    return true; /* The window advanced */
    @@ -820,7 +820,7 @@ static bool rxrpc_is_ack_valid(struct rxrpc_call *call,
    if (before(first_pkt, base))
    return false; /* firstPacket regressed */

    - if (after_eq(prev_pkt, call->ackr_prev_seq))
    + if (after_eq(prev_pkt, call->acks_prev_seq))
    return true; /* previousPacket hasn't regressed. */

    /* Some rx implementations put a serial number in previousPacket. */
    @@ -906,8 +906,8 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
    /* Discard any out-of-order or duplicate ACKs (outside lock). */
    if (!rxrpc_is_ack_valid(call, first_soft_ack, prev_pkt)) {
    trace_rxrpc_rx_discard_ack(call->debug_id, ack_serial,
    - first_soft_ack, call->ackr_first_seq,
    - prev_pkt, call->ackr_prev_seq);
    + first_soft_ack, call->acks_first_seq,
    + prev_pkt, call->acks_prev_seq);
    return;
    }

    @@ -922,14 +922,14 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
    /* Discard any out-of-order or duplicate ACKs (inside lock). */
    if (!rxrpc_is_ack_valid(call, first_soft_ack, prev_pkt)) {
    trace_rxrpc_rx_discard_ack(call->debug_id, ack_serial,
    - first_soft_ack, call->ackr_first_seq,
    - prev_pkt, call->ackr_prev_seq);
    + first_soft_ack, call->acks_first_seq,
    + prev_pkt, call->acks_prev_seq);
    goto out;
    }
    call->acks_latest_ts = skb->tstamp;

    - call->ackr_first_seq = first_soft_ack;
    - call->ackr_prev_seq = prev_pkt;
    + call->acks_first_seq = first_soft_ack;
    + call->acks_prev_seq = prev_pkt;

    /* Parse rwind and mtu sizes if provided. */
    if (buf.info.rxMTU)
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-06-07 19:57    [W:2.144 / U:0.828 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site