From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vlad Buslov Subject: [PATCH net-next v2 08/10] net: sched: protect block idr with spinlock Date: Mon, 17 Sep 2018 10:17:38 +0300 Message-ID: <1537168660-24032-9-git-send-email-vladbu@mellanox.com> References: <1537168660-24032-1-git-send-email-vladbu@mellanox.com> Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, davem@davemloft.net, stephen@networkplumber.org, ktkhai@virtuozzo.com, nicolas.dichtel@6wind.com, gregkh@linuxfoundation.org, mark.rutland@arm.com, leon@kernel.org, paulmck@linux.vnet.ibm.com, fw@strlen.de, dsahern@gmail.com, christian@brauner.io, lucien.xin@gmail.com, jakub.kicinski@netronome.com, jbenc@redhat.com, Vlad Buslov To: netdev@vger.kernel.org Return-path: Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:39794 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726742AbeIQMpS (ORCPT ); Mon, 17 Sep 2018 08:45:18 -0400 In-Reply-To: <1537168660-24032-1-git-send-email-vladbu@mellanox.com> Sender: netdev-owner@vger.kernel.org List-ID: Protect block idr access with spinlock, instead of relying on rtnl lock. Take tn->idr_lock spinlock during block insertion and removal. Signed-off-by: Vlad Buslov Acked-by: Jiri Pirko --- net/sched/cls_api.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 58b2d8443f6a..924723fb74f6 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -473,6 +473,7 @@ tcf_chain0_head_change_cb_del(struct tcf_block *block, } struct tcf_net { + spinlock_t idr_lock; /* Protects idr */ struct idr idr; }; @@ -482,16 +483,25 @@ static int tcf_block_insert(struct tcf_block *block, struct net *net, struct netlink_ext_ack *extack) { struct tcf_net *tn = net_generic(net, tcf_net_id); + int err; + + idr_preload(GFP_KERNEL); + spin_lock(&tn->idr_lock); + err = idr_alloc_u32(&tn->idr, block, &block->index, block->index, + GFP_NOWAIT); + spin_unlock(&tn->idr_lock); + idr_preload_end(); - return idr_alloc_u32(&tn->idr, block, &block->index, block->index, - GFP_KERNEL); + return err; } static void tcf_block_remove(struct tcf_block *block, struct net *net) { struct tcf_net *tn = net_generic(net, tcf_net_id); + spin_lock(&tn->idr_lock); idr_remove(&tn->idr, block->index); + spin_unlock(&tn->idr_lock); } static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q, @@ -2285,6 +2295,7 @@ static __net_init int tcf_net_init(struct net *net) { struct tcf_net *tn = net_generic(net, tcf_net_id); + spin_lock_init(&tn->idr_lock); idr_init(&tn->idr); return 0; } -- 2.7.5