From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Dumazet Subject: Re: [PATCH][next-next][v2] netlink: avoid to allocate full skb when sending to many devices Date: Thu, 20 Sep 2018 06:51:47 -0700 Message-ID: <549f8bea-bd5f-70da-bbf3-c2331ffbf964@gmail.com> References: <1537433690-24335-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-f194.google.com ([209.85.214.194]:43146 "EHLO mail-pl1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726990AbeITTfY (ORCPT ); Thu, 20 Sep 2018 15:35:24 -0400 Received: by mail-pl1-f194.google.com with SMTP id 38-v6so4392785plc.10 for ; Thu, 20 Sep 2018 06:51:49 -0700 (PDT) In-Reply-To: Content-Language: en-US Sender: netdev-owner@vger.kernel.org List-ID: On 09/20/2018 06:43 AM, Eric Dumazet wrote: > > And lastly this patch looks way too complicated to me. > You probably can write something much simpler. Something like : diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 930d17fa906c9ebf1cf7b6031ce0a22f9f66c0e4..e0a81beb4f37751421dbbe794ccf3d5a46bdf900 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -278,22 +278,26 @@ static bool netlink_filter_tap(const struct sk_buff *skb) return false; } -static int __netlink_deliver_tap_skb(struct sk_buff *skb, +static int __netlink_deliver_tap_skb(struct sk_buff **pskb, struct net_device *dev) { - struct sk_buff *nskb; + struct sk_buff *nskb, *skb = *pskb; struct sock *sk = skb->sk; int ret = -ENOMEM; if (!net_eq(dev_net(dev), sock_net(sk))) return 0; - dev_hold(dev); - - if (is_vmalloc_addr(skb->head)) + if (is_vmalloc_addr(skb->head)) { nskb = netlink_to_full_skb(skb, GFP_ATOMIC); - else - nskb = skb_clone(skb, GFP_ATOMIC); + if (!nskb) + return -ENOMEM; + consume_skb(skb); + skb = nskb; + *pskb = skb; + } + dev_hold(dev); + nskb = skb_clone(skb, GFP_ATOMIC); if (nskb) { nskb->dev = dev; nskb->protocol = htons((u16) sk->sk_protocol); @@ -318,7 +322,7 @@ static void __netlink_deliver_tap(struct sk_buff *skb, struct netlink_tap_net *n return; list_for_each_entry_rcu(tmp, &nn->netlink_tap_all, list) { - ret = __netlink_deliver_tap_skb(skb, tmp->dev); + ret = __netlink_deliver_tap_skb(&skb, tmp->dev); if (unlikely(ret)) break; }