Commit fda03fbb authored by Baruch Even's avatar Baruch Even Committed by David S. Miller

[TCP]: Advance fast path pointer for first block only

Only advance the SACK fast-path pointer for the first block, the
fast-path assumes that only the first block advances next time so we
should not move the cached skb for the next sack blocks.
Signed-off-by: default avatarBaruch Even <baruch@ev-en.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ffbc6111
...@@ -936,13 +936,16 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ ...@@ -936,13 +936,16 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
struct tcp_sock *tp = tcp_sk(sk); struct tcp_sock *tp = tcp_sk(sk);
unsigned char *ptr = ack_skb->h.raw + TCP_SKB_CB(ack_skb)->sacked; unsigned char *ptr = ack_skb->h.raw + TCP_SKB_CB(ack_skb)->sacked;
struct tcp_sack_block_wire *sp = (struct tcp_sack_block_wire *)(ptr+2); struct tcp_sack_block_wire *sp = (struct tcp_sack_block_wire *)(ptr+2);
struct sk_buff *cached_skb;
int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3; int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
int reord = tp->packets_out; int reord = tp->packets_out;
int prior_fackets; int prior_fackets;
u32 lost_retrans = 0; u32 lost_retrans = 0;
int flag = 0; int flag = 0;
int dup_sack = 0; int dup_sack = 0;
int cached_fack_count;
int i; int i;
int first_sack_index;
if (!tp->sacked_out) if (!tp->sacked_out)
tp->fackets_out = 0; tp->fackets_out = 0;
...@@ -1000,6 +1003,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ ...@@ -1000,6 +1003,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
} }
} }
first_sack_index = 0;
if (flag) if (flag)
num_sacks = 1; num_sacks = 1;
else { else {
...@@ -1016,6 +1020,10 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ ...@@ -1016,6 +1020,10 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
tmp = sp[j]; tmp = sp[j];
sp[j] = sp[j+1]; sp[j] = sp[j+1];
sp[j+1] = tmp; sp[j+1] = tmp;
/* Track where the first SACK block goes to */
if (j == first_sack_index)
first_sack_index = j+1;
} }
} }
...@@ -1025,20 +1033,22 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ ...@@ -1025,20 +1033,22 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
/* clear flag as used for different purpose in following code */ /* clear flag as used for different purpose in following code */
flag = 0; flag = 0;
/* Use SACK fastpath hint if valid */
cached_skb = tp->fastpath_skb_hint;
cached_fack_count = tp->fastpath_cnt_hint;
if (!cached_skb) {
cached_skb = sk->sk_write_queue.next;
cached_fack_count = 0;
}
for (i=0; i<num_sacks; i++, sp++) { for (i=0; i<num_sacks; i++, sp++) {
struct sk_buff *skb; struct sk_buff *skb;
__u32 start_seq = ntohl(sp->start_seq); __u32 start_seq = ntohl(sp->start_seq);
__u32 end_seq = ntohl(sp->end_seq); __u32 end_seq = ntohl(sp->end_seq);
int fack_count; int fack_count;
/* Use SACK fastpath hint if valid */ skb = cached_skb;
if (tp->fastpath_skb_hint) { fack_count = cached_fack_count;
skb = tp->fastpath_skb_hint;
fack_count = tp->fastpath_cnt_hint;
} else {
skb = sk->sk_write_queue.next;
fack_count = 0;
}
/* Event "B" in the comment above. */ /* Event "B" in the comment above. */
if (after(end_seq, tp->high_seq)) if (after(end_seq, tp->high_seq))
...@@ -1048,8 +1058,12 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ ...@@ -1048,8 +1058,12 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
int in_sack, pcount; int in_sack, pcount;
u8 sacked; u8 sacked;
cached_skb = skb;
cached_fack_count = fack_count;
if (i == first_sack_index) {
tp->fastpath_skb_hint = skb; tp->fastpath_skb_hint = skb;
tp->fastpath_cnt_hint = fack_count; tp->fastpath_cnt_hint = fack_count;
}
/* The retransmission queue is always in order, so /* The retransmission queue is always in order, so
* we can short-circuit the walk early. * we can short-circuit the walk early.
......
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