From: "'Alexander Lobakin'" <aloba...@pm.me> From: Dongseok Yi" <dseok...@samsung.com> Date: Wed, 13 Jan 2021 12:59:45 +0900
> On 2021-01-13 12:10, Alexander Duyck wrote: >> On 1/12/21 1:16 PM, Alexander Lobakin wrote: >>> Commit 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.") actually >>> not only added a support for fraglisted UDP GRO, but also tweaked >>> some logics the way that non-fraglisted UDP GRO started to work for >>> forwarding too. >>> Tests showed that currently forwarding and NATing of plain UDP GRO >>> packets are performed fully correctly, regardless if the target >>> netdevice has a support for hardware/driver GSO UDP L4 or not. >>> Add the last element and allow to form plain UDP GRO packets if >>> there is no socket -> we are on forwarding path. >>> > > Your patch is very similar with the RFC what I submitted but has > different approach. My concern was NAT forwarding. > https://lore.kernel.org/patchwork/patch/1362257/ Not really. You tried to forbid forwarding of fraglisted UDP GRO packets, I allow forwarding of plain UDP GRO packets. With my patch on, you can switch between plain and fraglisted UDP GRO with the command: ethtool -K eth0 rx-gro-list on/off > Nevertheless, I agreed with your idea that allow fraglisted UDP GRO > if there is socket. Recheck my change. There's ||, not &&. As I said in the commit message, forwarding and NATing of plain UDP GRO packets are performed correctly, both with and without driver-side support, so it's safe to enable. Also, as I said in reply to your RFC, NATing of UDP GRO fraglists is performed correctly if driver is aware of it and advertises a support for fraglist GSO. If not, then there may be problems you described. But the idea to forbid forwarding and NATing of any UDP GRO skbs is an absolute overkill. >>> Plain UDP GRO forwarding even shows better performance than fraglisted >>> UDP GRO in some cases due to not wasting one skbuff_head per every >>> segment. >>> >>> Signed-off-by: Alexander Lobakin <aloba...@pm.me> >>> --- >>> net/ipv4/udp_offload.c | 5 +++-- >>> 1 file changed, 3 insertions(+), 2 deletions(-) >>> >>> diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c >>> index ff39e94781bf..9d71df3d52ce 100644 >>> --- a/net/ipv4/udp_offload.c >>> +++ b/net/ipv4/udp_offload.c >>> @@ -460,12 +460,13 @@ struct sk_buff *udp_gro_receive(struct list_head >>> *head, struct sk_buff *skb, >>> if (skb->dev->features & NETIF_F_GRO_FRAGLIST) >>> NAPI_GRO_CB(skb)->is_flist = sk ? !udp_sk(sk)->gro_enabled: 1; > > is_flist can be true even if !sk. > >>> >>> - if ((sk && udp_sk(sk)->gro_enabled) || NAPI_GRO_CB(skb)->is_flist) { >>> + if (!sk || (sk && udp_sk(sk)->gro_enabled) || > > Actually sk would be NULL by udp_encap_needed_key in udp4_gro_receive > or udp6_gro_receive. > >>> + NAPI_GRO_CB(skb)->is_flist) { >>> pp = call_gro_receive(udp_gro_receive_segment, head, skb); > > udp_gro_receive_segment will check is_flist first and try to do > fraglisted UDP GRO. Can you check what I'm missing? I think you miss that is_flist is set to true *only* if the receiving netdevice has NETIF_F_GRO_FRAGLIST feature on. If it's not, stack will form a non-fraglisted UDP GRO skb. That was tested multiple times. >>> return pp; >>> } >>> >> >> The second check for sk in "(sk && udp_sk(sk)->gro_enabled)" is >> redundant and can be dropped. You already verified it is present when >> you checked for !sk before the logical OR. Alex are right, I'll simplify the condition in v2. Thanks! > Sorry, Alexander Duyck. I believe Alexander Lobakin will answer this. > >>> - if (!sk || NAPI_GRO_CB(skb)->encap_mark || >>> + if (NAPI_GRO_CB(skb)->encap_mark || >>> (skb->ip_summed != CHECKSUM_PARTIAL && >>> NAPI_GRO_CB(skb)->csum_cnt == 0 && >>> !NAPI_GRO_CB(skb)->csum_valid) || >>> Al