On Tue, 3 Nov 2020 11:18:25 -0800 Saeed Mahameed wrote: > From: Maxim Mikityanskiy <maxi...@mellanox.com> > > On resync, the driver calls inet_lookup_established > (__inet6_lookup_established) that increases sk_refcnt of the socket. To > decrease it, the driver set skb->destructor to sock_edemux. However, it > didn't work well, because the TCP stack also sets this destructor for > early demux, and the refcount gets decreased only once
Why is the stack doing early_demux if there is already a socket assigned? Or is it not early_demux but something else? Can you point us at the code? IPv4: if (net->ipv4.sysctl_ip_early_demux && !skb_dst(skb) && !skb->sk && <============ !ip_is_fragment(iph)) { const struct net_protocol *ipprot; int protocol = iph->protocol; ipprot = rcu_dereference(inet_protos[protocol]); if (ipprot && (edemux = READ_ONCE(ipprot->early_demux))) { err = INDIRECT_CALL_2(edemux, tcp_v4_early_demux, udp_v4_early_demux, skb); if (unlikely(err)) goto drop_error; /* must reload iph, skb->head might have changed */ iph = ip_hdr(skb); } } IPv6: if (net->ipv4.sysctl_ip_early_demux && !skb_dst(skb) && skb->sk == NULL) { ~~~~~~~~~~~~~~~ const struct inet6_protocol *ipprot; ipprot = rcu_dereference(inet6_protos[ipv6_hdr(skb)->nexthdr]); if (ipprot && (edemux = READ_ONCE(ipprot->early_demux))) INDIRECT_CALL_2(edemux, tcp_v6_early_demux, udp_v6_early_demux, skb); }