Message ID | 20201103191830.60151-1-saeedm@nvidia.com |
---|---|
Headers | show |
Series | mlx5 fixes 2020-11-03 | expand |
On Tue, 3 Nov 2020 11:18:22 -0800 Saeed Mahameed wrote: > From: Maor Dickman <maord@nvidia.com> > > Modify header actions are allocated during parse tc actions and only > freed during the flow creation, however, on error flow the allocated > memory is wrongly unfreed. > > Fix this by calling dealloc_mod_hdr_actions in __mlx5e_add_fdb_flow > and mlx5e_add_nic_flow error flow. > > Fixes: d7e75a325cb2 ("net/mlx5e: Add offloading of E-Switch TC pedit (header re-write) action"') > Fixes: 2f4fe4cab073 ("net/mlx5e: Add offloading of NIC TC pedit (header re-write) actions") > Signed-off-by: Maor Dickman <maord@nvidia.com> > Reviewed-by: Paul Blakey <paulb@nvidia.com> > Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> Sorry, I didn't look at the warnings for you patches yesterday. Fixes tag: Fixes: d7e75a325cb2 ("net/mlx5e: Add offloading of E-Switch TC pedit (header re-write) action"') Has these problem(s): - Subject has leading but no trailing quotes - Subject does not match target commit subject Just use git log -1 --format='Fixes: %h ("%s")'
On Tue, 3 Nov 2020 11:18:25 -0800 Saeed Mahameed wrote: > From: Maxim Mikityanskiy <maximmi@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); }
On 2020-11-05 00:59, Jakub Kicinski wrote: > On Tue, 3 Nov 2020 11:18:25 -0800 Saeed Mahameed wrote: >> From: Maxim Mikityanskiy <maximmi@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? I thought this was the code that was in conflict with setting skb->destructor in the driver: void skb_set_owner_w(struct sk_buff *skb, struct sock *sk) { skb_orphan(skb); skb->sk = sk; #ifdef CONFIG_INET if (unlikely(!sk_fullsock(sk))) { skb->destructor = sock_edemux; sock_hold(sk); return; } #endif However, after taking another look, it seems that the root cause is somewhere else. This piece of code actually calls skb_orphan before reassigning the destructor. I'll debug it further to try to find where the destructor is replaced or just not called. > 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); > } >