Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756780AbdLPJzd (ORCPT ); Sat, 16 Dec 2017 04:55:33 -0500 Received: from cmccmta1.chinamobile.com ([221.176.66.79]:27191 "EHLO cmccmta1.chinamobile.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756636AbdLPJz1 (ORCPT ); Sat, 16 Dec 2017 04:55:27 -0500 X-RM-TRANSID: 2ee25a34ed8b41d-4dece X-RM-TagInfo: emlType=0 X-RM-SPAM-FLAG: 00000000 X-RM-TRANSID: 2ee35a34ed8a412-bec35 From: Haishuang Yan To: "David S. Miller" , Eric Dumazet Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Haishuang Yan Subject: [PATCH net-next 2/2] geneve: speedup geneve tunnels dismantle Date: Sat, 16 Dec 2017 17:54:50 +0800 Message-Id: <1513418090-8595-3-git-send-email-yanhaishuang@cmss.chinamobile.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1513418090-8595-1-git-send-email-yanhaishuang@cmss.chinamobile.com> References: <1513418090-8595-1-git-send-email-yanhaishuang@cmss.chinamobile.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2121 Lines: 71 Since we now hold RTNL lock in geneve_exit_net, it's better batch them to speedup geneve tunnel dismantle. Signed-off-by: Haishuang Yan --- drivers/net/geneve.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index b718a02..667c44f 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -1638,19 +1638,16 @@ static __net_init int geneve_init_net(struct net *net) return 0; } -static void __net_exit geneve_exit_net(struct net *net) +static void geneve_destroy_tunnels(struct net *net, struct list_head *head) { struct geneve_net *gn = net_generic(net, geneve_net_id); struct geneve_dev *geneve, *next; struct net_device *dev, *aux; - LIST_HEAD(list); - - rtnl_lock(); /* gather any geneve devices that were moved into this ns */ for_each_netdev_safe(net, dev, aux) if (dev->rtnl_link_ops == &geneve_link_ops) - unregister_netdevice_queue(dev, &list); + unregister_netdevice_queue(dev, head); /* now gather any other geneve devices that were created in this ns */ list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) { @@ -1658,18 +1655,29 @@ static void __net_exit geneve_exit_net(struct net *net) * to the list by the previous loop. */ if (!net_eq(dev_net(geneve->dev), net)) - unregister_netdevice_queue(geneve->dev, &list); + unregister_netdevice_queue(geneve->dev, head); } + WARN_ON_ONCE(!list_empty(&gn->sock_list)); +} + +static void __net_exit geneve_exit_batch_net(struct list_head *net_list) +{ + struct net *net; + LIST_HEAD(list); + + rtnl_lock(); + list_for_each_entry(net, net_list, exit_list) + geneve_destroy_tunnels(net, &list); + /* unregister the devices gathered above */ unregister_netdevice_many(&list); rtnl_unlock(); - WARN_ON_ONCE(!list_empty(&gn->sock_list)); } static struct pernet_operations geneve_net_ops = { .init = geneve_init_net, - .exit = geneve_exit_net, + .exit_batch = geneve_exit_batch_net, .id = &geneve_net_id, .size = sizeof(struct geneve_net), }; -- 1.8.3.1