From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Dumazet Subject: Re: [PATCH][RFC] udp: cache sock to avoid searching it twice Date: Fri, 9 Nov 2018 09:25:53 -0800 Message-ID: <0c6a070f-d2ac-2ffc-00d5-097fe84ae42c@gmail.com> References: <1541744479-12810-1-git-send-email-lirongqing@baidu.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit To: Li RongQing , netdev@vger.kernel.org Return-path: Received: from mail-pl1-f196.google.com ([209.85.214.196]:34748 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728026AbeKJDH1 (ORCPT ); Fri, 9 Nov 2018 22:07:27 -0500 Received: by mail-pl1-f196.google.com with SMTP id f12-v6so1241510plo.1 for ; Fri, 09 Nov 2018 09:25:55 -0800 (PST) In-Reply-To: <1541744479-12810-1-git-send-email-lirongqing@baidu.com> Content-Language: en-US Sender: netdev-owner@vger.kernel.org List-ID: On 11/08/2018 10:21 PM, Li RongQing wrote: > GRO for UDP needs to lookup socket twice, first is in gro receive, > second is gro complete, so if store sock to skb to avoid looking up > twice, this can give small performance boost > > netperf -t UDP_RR -l 10 > > Before: > Rate per sec: 28746.01 > After: > Rate per sec: 29401.67 > > Signed-off-by: Li RongQing > --- > net/ipv4/udp_offload.c | 18 +++++++++++++++++- > 1 file changed, 17 insertions(+), 1 deletion(-) > > diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c > index 0646d61f4fa8..429570112a33 100644 > --- a/net/ipv4/udp_offload.c > +++ b/net/ipv4/udp_offload.c > @@ -408,6 +408,11 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb, > > if (udp_sk(sk)->gro_enabled) { > pp = call_gro_receive(udp_gro_receive_segment, head, skb); > + > + if (!IS_ERR(pp) && NAPI_GRO_CB(pp)->count > 1) { > + sock_hold(sk); > + pp->sk = sk; You also have to set pp->destructor to sock_edemux flush_gro_hash -> kfree_skb() If there is no destructor, the reference on pp->sk will never be released. > + } > rcu_read_unlock(); > return pp; > } > @@ -444,6 +449,10 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb, > skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr)); > pp = call_gro_receive_sk(udp_sk(sk)->gro_receive, sk, head, skb); > > + if (!IS_ERR(pp) && NAPI_GRO_CB(pp)->count > 1) { > + sock_hold(sk); > + pp->sk = sk; > + } > out_unlock: > rcu_read_unlock(); > skb_gro_flush_final(skb, pp, flush); > @@ -502,7 +511,9 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff, > uh->len = newlen; > > rcu_read_lock(); > - sk = (*lookup)(skb, uh->source, uh->dest); > + sk = skb->sk; > + if (!sk) > + sk = (*lookup)(skb, uh->source, uh->dest); > if (sk && udp_sk(sk)->gro_enabled) { > err = udp_gro_complete_segment(skb); > } else if (sk && udp_sk(sk)->gro_complete) { > @@ -516,6 +527,11 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff, > err = udp_sk(sk)->gro_complete(sk, skb, > nhoff + sizeof(struct udphdr)); > } > + > + if (skb->sk) { > + sock_put(skb->sk); > + skb->sk = NULL; > + } > rcu_read_unlock(); > > if (skb->remcsum_offload) >