diff options
| author | Eric Dumazet <edumazet@google.com> | 2014-10-30 13:32:34 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-10-30 19:58:30 -0400 |
| commit | 39bb5e62867de82b269b07df900165029b928359 (patch) | |
| tree | f0cbefb0eee4eda2697c4e2fd6e0ad3ee7331f43 /include/linux | |
| parent | 14051f0452a2c26a3f4791e6ad6a435e8f1945ff (diff) | |
net: skb_fclone_busy() needs to detect orphaned skb
Some drivers are unable to perform TX completions in a bound time.
They instead call skb_orphan()
Problem is skb_fclone_busy() has to detect this case, otherwise
we block TCP retransmits and can freeze unlucky tcp sessions on
mostly idle hosts.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Fixes: 1f3279ae0c13 ("tcp: avoid retransmits of TCP packets hanging in host queues")
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/skbuff.h | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 5884f95ff0e9..6c8b6f604e76 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -799,15 +799,19 @@ struct sk_buff_fclones { | |||
| 799 | * @skb: buffer | 799 | * @skb: buffer |
| 800 | * | 800 | * |
| 801 | * Returns true is skb is a fast clone, and its clone is not freed. | 801 | * Returns true is skb is a fast clone, and its clone is not freed. |
| 802 | * Some drivers call skb_orphan() in their ndo_start_xmit(), | ||
| 803 | * so we also check that this didnt happen. | ||
| 802 | */ | 804 | */ |
| 803 | static inline bool skb_fclone_busy(const struct sk_buff *skb) | 805 | static inline bool skb_fclone_busy(const struct sock *sk, |
| 806 | const struct sk_buff *skb) | ||
| 804 | { | 807 | { |
| 805 | const struct sk_buff_fclones *fclones; | 808 | const struct sk_buff_fclones *fclones; |
| 806 | 809 | ||
| 807 | fclones = container_of(skb, struct sk_buff_fclones, skb1); | 810 | fclones = container_of(skb, struct sk_buff_fclones, skb1); |
| 808 | 811 | ||
| 809 | return skb->fclone == SKB_FCLONE_ORIG && | 812 | return skb->fclone == SKB_FCLONE_ORIG && |
| 810 | fclones->skb2.fclone == SKB_FCLONE_CLONE; | 813 | fclones->skb2.fclone == SKB_FCLONE_CLONE && |
| 814 | fclones->skb2.sk == sk; | ||
| 811 | } | 815 | } |
| 812 | 816 | ||
| 813 | static inline struct sk_buff *alloc_skb_fclone(unsigned int size, | 817 | static inline struct sk_buff *alloc_skb_fclone(unsigned int size, |
