aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2018-11-19 20:45:55 -0500
committerDavid S. Miller <davem@davemloft.net>2018-11-20 13:25:47 -0500
commitade9628ed049242fac5dd94730881f8c5e244634 (patch)
treed015d9a05254a6a6e05fc64f17f32743610b5d9d /net/ipv4/tcp_ipv4.c
parentb2c851006386c1c5c0e55eab4a7f60da2a3e25b3 (diff)
tcp: drop dst in tcp_add_backlog()
Under stress, softirq rx handler often hits a socket owned by the user, and has to queue the packet into socket backlog. When this happens, skb dst refcount is taken before we escape rcu protected region. This is done from __sk_add_backlog() calling skb_dst_force(). Consumer will have to perform the opposite costly operation. AFAIK nothing in tcp stack requests the dst after skb was stored in the backlog. If this was the case, we would have had failures already since skb_dst_force() can end up clearing skb dst anyway. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 0952d4b772e7..795605a23275 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1634,6 +1634,8 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
1634 */ 1634 */
1635 skb_condense(skb); 1635 skb_condense(skb);
1636 1636
1637 skb_dst_drop(skb);
1638
1637 if (unlikely(sk_add_backlog(sk, skb, limit))) { 1639 if (unlikely(sk_add_backlog(sk, skb, limit))) {
1638 bh_unlock_sock(sk); 1640 bh_unlock_sock(sk);
1639 __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPBACKLOGDROP); 1641 __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPBACKLOGDROP);