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);
        }

Reply via email to