lkml.org 
[lkml]   [2012]   [Feb]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[ 33/73] tcp: allow tcp_sacktag_one() to tag ranges not aligned with skbs
    3.0-stable review patch.  If anyone has any objections, please let me know.

    ------------------


    From: Neal Cardwell <ncardwell@google.com>

    [ Upstream commit cc9a672ee522d4805495b98680f4a3db5d0a0af9 ]

    This commit allows callers of tcp_sacktag_one() to pass in sequence
    ranges that do not align with skb boundaries, as tcp_shifted_skb()
    needs to do in an upcoming fix in this patch series.

    In fact, now tcp_sacktag_one() does not need to depend on an input skb
    at all, which makes its semantics and dependencies more clear.

    Signed-off-by: Neal Cardwell <ncardwell@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/ipv4/tcp_input.c | 36 ++++++++++++++++++++++--------------
    1 file changed, 22 insertions(+), 14 deletions(-)

    --- a/net/ipv4/tcp_input.c
    +++ b/net/ipv4/tcp_input.c
    @@ -1289,25 +1289,26 @@ static int tcp_match_skb_to_sack(struct
    return in_sack;
    }

    -static u8 tcp_sacktag_one(struct sk_buff *skb, struct sock *sk,
    - struct tcp_sacktag_state *state,
    +/* Mark the given newly-SACKed range as such, adjusting counters and hints. */
    +static u8 tcp_sacktag_one(struct sock *sk,
    + struct tcp_sacktag_state *state, u8 sacked,
    + u32 start_seq, u32 end_seq,
    int dup_sack, int pcount)
    {
    struct tcp_sock *tp = tcp_sk(sk);
    - u8 sacked = TCP_SKB_CB(skb)->sacked;
    int fack_count = state->fack_count;

    /* Account D-SACK for retransmitted packet. */
    if (dup_sack && (sacked & TCPCB_RETRANS)) {
    if (tp->undo_marker && tp->undo_retrans &&
    - after(TCP_SKB_CB(skb)->end_seq, tp->undo_marker))
    + after(end_seq, tp->undo_marker))
    tp->undo_retrans--;
    if (sacked & TCPCB_SACKED_ACKED)
    state->reord = min(fack_count, state->reord);
    }

    /* Nothing to do; acked frame is about to be dropped (was ACKed). */
    - if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
    + if (!after(end_seq, tp->snd_una))
    return sacked;

    if (!(sacked & TCPCB_SACKED_ACKED)) {
    @@ -1326,13 +1327,13 @@ static u8 tcp_sacktag_one(struct sk_buff
    /* New sack for not retransmitted frame,
    * which was in hole. It is reordering.
    */
    - if (before(TCP_SKB_CB(skb)->seq,
    + if (before(start_seq,
    tcp_highest_sack_seq(tp)))
    state->reord = min(fack_count,
    state->reord);

    /* SACK enhanced F-RTO (RFC4138; Appendix B) */
    - if (!after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark))
    + if (!after(end_seq, tp->frto_highmark))
    state->flag |= FLAG_ONLY_ORIG_SACKED;
    }

    @@ -1350,8 +1351,7 @@ static u8 tcp_sacktag_one(struct sk_buff

    /* Lost marker hint past SACKed? Tweak RFC3517 cnt */
    if (!tcp_is_fack(tp) && (tp->lost_skb_hint != NULL) &&
    - before(TCP_SKB_CB(skb)->seq,
    - TCP_SKB_CB(tp->lost_skb_hint)->seq))
    + before(start_seq, TCP_SKB_CB(tp->lost_skb_hint)->seq))
    tp->lost_cnt_hint += pcount;

    if (fack_count > tp->fackets_out)
    @@ -1407,7 +1407,11 @@ static int tcp_shifted_skb(struct sock *
    }

    /* We discard results */
    - tcp_sacktag_one(skb, sk, state, dup_sack, pcount);
    + tcp_sacktag_one(sk, state,
    + TCP_SKB_CB(skb)->sacked,
    + TCP_SKB_CB(skb)->seq,
    + TCP_SKB_CB(skb)->end_seq,
    + dup_sack, pcount);

    /* Difference in this won't matter, both ACKed by the same cumul. ACK */
    TCP_SKB_CB(prev)->sacked |= (TCP_SKB_CB(skb)->sacked & TCPCB_EVER_RETRANS);
    @@ -1646,10 +1650,14 @@ static struct sk_buff *tcp_sacktag_walk(
    break;

    if (in_sack) {
    - TCP_SKB_CB(skb)->sacked = tcp_sacktag_one(skb, sk,
    - state,
    - dup_sack,
    - tcp_skb_pcount(skb));
    + TCP_SKB_CB(skb)->sacked =
    + tcp_sacktag_one(sk,
    + state,
    + TCP_SKB_CB(skb)->sacked,
    + TCP_SKB_CB(skb)->seq,
    + TCP_SKB_CB(skb)->end_seq,
    + dup_sack,
    + tcp_skb_pcount(skb));

    if (!before(TCP_SKB_CB(skb)->seq,
    tcp_highest_sack_seq(tp)))



    \
     
     \ /
      Last update: 2012-02-28 02:37    [W:0.026 / U:61.048 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site