diff options
| -rw-r--r-- | include/linux/netdevice.h | 3 | ||||
| -rw-r--r-- | include/net/tcp.h | 1 | ||||
| -rw-r--r-- | net/core/dev.c | 2 | ||||
| -rw-r--r-- | net/core/skbuff.c | 6 | ||||
| -rw-r--r-- | net/ipv4/tcp_input.c | 6 | ||||
| -rw-r--r-- | net/ipv4/tcp_output.c | 15 |
6 files changed, 24 insertions, 9 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index f8eda0276f03..a848ffc327f4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -1488,6 +1488,9 @@ struct napi_gro_cb { | |||
| 1488 | 1488 | ||
| 1489 | /* Used in ipv6_gro_receive() */ | 1489 | /* Used in ipv6_gro_receive() */ |
| 1490 | int proto; | 1490 | int proto; |
| 1491 | |||
| 1492 | /* used in skb_gro_receive() slow path */ | ||
| 1493 | struct sk_buff *last; | ||
| 1491 | }; | 1494 | }; |
| 1492 | 1495 | ||
| 1493 | #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb) | 1496 | #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb) |
diff --git a/include/net/tcp.h b/include/net/tcp.h index 6feeccd83dd7..4af45e33105d 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
| @@ -525,6 +525,7 @@ static inline __u32 cookie_v6_init_sequence(struct sock *sk, | |||
| 525 | extern void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss, | 525 | extern void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss, |
| 526 | int nonagle); | 526 | int nonagle); |
| 527 | extern bool tcp_may_send_now(struct sock *sk); | 527 | extern bool tcp_may_send_now(struct sock *sk); |
| 528 | extern int __tcp_retransmit_skb(struct sock *, struct sk_buff *); | ||
| 528 | extern int tcp_retransmit_skb(struct sock *, struct sk_buff *); | 529 | extern int tcp_retransmit_skb(struct sock *, struct sk_buff *); |
| 529 | extern void tcp_retransmit_timer(struct sock *sk); | 530 | extern void tcp_retransmit_timer(struct sock *sk); |
| 530 | extern void tcp_xmit_retransmit_queue(struct sock *); | 531 | extern void tcp_xmit_retransmit_queue(struct sock *); |
diff --git a/net/core/dev.c b/net/core/dev.c index c0946cb2b354..e5942bf45a6d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -3451,6 +3451,8 @@ static int napi_gro_complete(struct sk_buff *skb) | |||
| 3451 | struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK]; | 3451 | struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK]; |
| 3452 | int err = -ENOENT; | 3452 | int err = -ENOENT; |
| 3453 | 3453 | ||
| 3454 | BUILD_BUG_ON(sizeof(struct napi_gro_cb) > sizeof(skb->cb)); | ||
| 3455 | |||
| 3454 | if (NAPI_GRO_CB(skb)->count == 1) { | 3456 | if (NAPI_GRO_CB(skb)->count == 1) { |
| 3455 | skb_shinfo(skb)->gso_size = 0; | 3457 | skb_shinfo(skb)->gso_size = 0; |
| 3456 | goto out; | 3458 | goto out; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 4007c1437fda..3f0636cd76cd 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -3004,7 +3004,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
| 3004 | skb_shinfo(nskb)->gso_size = pinfo->gso_size; | 3004 | skb_shinfo(nskb)->gso_size = pinfo->gso_size; |
| 3005 | pinfo->gso_size = 0; | 3005 | pinfo->gso_size = 0; |
| 3006 | skb_header_release(p); | 3006 | skb_header_release(p); |
| 3007 | nskb->prev = p; | 3007 | NAPI_GRO_CB(nskb)->last = p; |
| 3008 | 3008 | ||
| 3009 | nskb->data_len += p->len; | 3009 | nskb->data_len += p->len; |
| 3010 | nskb->truesize += p->truesize; | 3010 | nskb->truesize += p->truesize; |
| @@ -3030,8 +3030,8 @@ merge: | |||
| 3030 | 3030 | ||
| 3031 | __skb_pull(skb, offset); | 3031 | __skb_pull(skb, offset); |
| 3032 | 3032 | ||
| 3033 | p->prev->next = skb; | 3033 | NAPI_GRO_CB(p)->last->next = skb; |
| 3034 | p->prev = skb; | 3034 | NAPI_GRO_CB(p)->last = skb; |
| 3035 | skb_header_release(skb); | 3035 | skb_header_release(skb); |
| 3036 | 3036 | ||
| 3037 | done: | 3037 | done: |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 609ff98aeb47..181fc8234a52 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -5645,7 +5645,11 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, | |||
| 5645 | tcp_fastopen_cache_set(sk, mss, cookie, syn_drop); | 5645 | tcp_fastopen_cache_set(sk, mss, cookie, syn_drop); |
| 5646 | 5646 | ||
| 5647 | if (data) { /* Retransmit unacked data in SYN */ | 5647 | if (data) { /* Retransmit unacked data in SYN */ |
| 5648 | tcp_retransmit_skb(sk, data); | 5648 | tcp_for_write_queue_from(data, sk) { |
| 5649 | if (data == tcp_send_head(sk) || | ||
| 5650 | __tcp_retransmit_skb(sk, data)) | ||
| 5651 | break; | ||
| 5652 | } | ||
| 5649 | tcp_rearm_rto(sk); | 5653 | tcp_rearm_rto(sk); |
| 5650 | return true; | 5654 | return true; |
| 5651 | } | 5655 | } |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 2798706cb063..948ac275b9b5 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -2309,12 +2309,11 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to, | |||
| 2309 | * state updates are done by the caller. Returns non-zero if an | 2309 | * state updates are done by the caller. Returns non-zero if an |
| 2310 | * error occurred which prevented the send. | 2310 | * error occurred which prevented the send. |
| 2311 | */ | 2311 | */ |
| 2312 | int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | 2312 | int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) |
| 2313 | { | 2313 | { |
| 2314 | struct tcp_sock *tp = tcp_sk(sk); | 2314 | struct tcp_sock *tp = tcp_sk(sk); |
| 2315 | struct inet_connection_sock *icsk = inet_csk(sk); | 2315 | struct inet_connection_sock *icsk = inet_csk(sk); |
| 2316 | unsigned int cur_mss; | 2316 | unsigned int cur_mss; |
| 2317 | int err; | ||
| 2318 | 2317 | ||
| 2319 | /* Inconslusive MTU probe */ | 2318 | /* Inconslusive MTU probe */ |
| 2320 | if (icsk->icsk_mtup.probe_size) { | 2319 | if (icsk->icsk_mtup.probe_size) { |
| @@ -2387,11 +2386,17 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
| 2387 | if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { | 2386 | if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { |
| 2388 | struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, | 2387 | struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, |
| 2389 | GFP_ATOMIC); | 2388 | GFP_ATOMIC); |
| 2390 | err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : | 2389 | return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : |
| 2391 | -ENOBUFS; | 2390 | -ENOBUFS; |
| 2392 | } else { | 2391 | } else { |
| 2393 | err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); | 2392 | return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); |
| 2394 | } | 2393 | } |
| 2394 | } | ||
| 2395 | |||
| 2396 | int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | ||
| 2397 | { | ||
| 2398 | struct tcp_sock *tp = tcp_sk(sk); | ||
| 2399 | int err = __tcp_retransmit_skb(sk, skb); | ||
| 2395 | 2400 | ||
| 2396 | if (err == 0) { | 2401 | if (err == 0) { |
| 2397 | /* Update global TCP statistics. */ | 2402 | /* Update global TCP statistics. */ |
