diff options
Diffstat (limited to 'net/core/sock.c')
-rw-r--r-- | net/core/sock.c | 23 |
1 files changed, 8 insertions, 15 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index 79c6aee6af9b..727f924b7f91 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -139,10 +139,7 @@ | |||
139 | 139 | ||
140 | #include <trace/events/sock.h> | 140 | #include <trace/events/sock.h> |
141 | 141 | ||
142 | #ifdef CONFIG_INET | ||
143 | #include <net/tcp.h> | 142 | #include <net/tcp.h> |
144 | #endif | ||
145 | |||
146 | #include <net/busy_poll.h> | 143 | #include <net/busy_poll.h> |
147 | 144 | ||
148 | static DEFINE_MUTEX(proto_list_mutex); | 145 | static DEFINE_MUTEX(proto_list_mutex); |
@@ -1803,28 +1800,24 @@ EXPORT_SYMBOL(skb_set_owner_w); | |||
1803 | * delay queue. We want to allow the owner socket to send more | 1800 | * delay queue. We want to allow the owner socket to send more |
1804 | * packets, as if they were already TX completed by a typical driver. | 1801 | * packets, as if they were already TX completed by a typical driver. |
1805 | * But we also want to keep skb->sk set because some packet schedulers | 1802 | * But we also want to keep skb->sk set because some packet schedulers |
1806 | * rely on it (sch_fq for example). So we set skb->truesize to a small | 1803 | * rely on it (sch_fq for example). |
1807 | * amount (1) and decrease sk_wmem_alloc accordingly. | ||
1808 | */ | 1804 | */ |
1809 | void skb_orphan_partial(struct sk_buff *skb) | 1805 | void skb_orphan_partial(struct sk_buff *skb) |
1810 | { | 1806 | { |
1811 | /* If this skb is a TCP pure ACK or already went here, | 1807 | if (skb_is_tcp_pure_ack(skb)) |
1812 | * we have nothing to do. 2 is already a very small truesize. | ||
1813 | */ | ||
1814 | if (skb->truesize <= 2) | ||
1815 | return; | 1808 | return; |
1816 | 1809 | ||
1817 | /* TCP stack sets skb->ooo_okay based on sk_wmem_alloc, | ||
1818 | * so we do not completely orphan skb, but transfert all | ||
1819 | * accounted bytes but one, to avoid unexpected reorders. | ||
1820 | */ | ||
1821 | if (skb->destructor == sock_wfree | 1810 | if (skb->destructor == sock_wfree |
1822 | #ifdef CONFIG_INET | 1811 | #ifdef CONFIG_INET |
1823 | || skb->destructor == tcp_wfree | 1812 | || skb->destructor == tcp_wfree |
1824 | #endif | 1813 | #endif |
1825 | ) { | 1814 | ) { |
1826 | atomic_sub(skb->truesize - 1, &skb->sk->sk_wmem_alloc); | 1815 | struct sock *sk = skb->sk; |
1827 | skb->truesize = 1; | 1816 | |
1817 | if (atomic_inc_not_zero(&sk->sk_refcnt)) { | ||
1818 | atomic_sub(skb->truesize, &sk->sk_wmem_alloc); | ||
1819 | skb->destructor = sock_efree; | ||
1820 | } | ||
1828 | } else { | 1821 | } else { |
1829 | skb_orphan(skb); | 1822 | skb_orphan(skb); |
1830 | } | 1823 | } |