From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vlad Buslov Subject: [PATCH net-next v2 07/10] net: sched: implement functions to put and flush all chains Date: Mon, 17 Sep 2018 10:17:37 +0300 Message-ID: <1537168660-24032-8-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]:39810 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727460AbeIQMpT (ORCPT ); Mon, 17 Sep 2018 08:45:19 -0400 In-Reply-To: <1537168660-24032-1-git-send-email-vladbu@mellanox.com> Sender: netdev-owner@vger.kernel.org List-ID: Extract code that flushes and puts all chains on tcf block to two standalone function to be shared with functions that locklessly get/put reference to block. Signed-off-by: Vlad Buslov Acked-by: Jiri Pirko --- net/sched/cls_api.c | 55 +++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index c3c7d4e2f84c..58b2d8443f6a 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -538,6 +538,31 @@ static void tcf_qdisc_put(struct Qdisc *q, bool rtnl_held) qdisc_put_unlocked(q); } +static void tcf_block_flush_all_chains(struct tcf_block *block) +{ + struct tcf_chain *chain; + + /* Hold a refcnt for all chains, so that they don't disappear + * while we are iterating. + */ + list_for_each_entry(chain, &block->chain_list, list) + tcf_chain_hold(chain); + + list_for_each_entry(chain, &block->chain_list, list) + tcf_chain_flush(chain); +} + +static void tcf_block_put_all_chains(struct tcf_block *block) +{ + struct tcf_chain *chain, *tmp; + + /* At this point, all the chains should have refcnt >= 1. */ + list_for_each_entry_safe(chain, tmp, &block->chain_list, list) { + tcf_chain_put_explicitly_created(chain); + tcf_chain_put(chain); + } +} + /* Find tcf block. * Set q, parent, cl when appropriate. */ @@ -795,8 +820,6 @@ EXPORT_SYMBOL(tcf_block_get); void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q, struct tcf_block_ext_info *ei) { - struct tcf_chain *chain, *tmp; - if (!block) return; tcf_chain0_head_change_cb_del(block, ei); @@ -813,32 +836,14 @@ void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q, if (tcf_block_shared(block)) tcf_block_remove(block, block->net); - - if (!free_block) { - /* Hold a refcnt for all chains, so that they don't - * disappear while we are iterating. - */ - list_for_each_entry(chain, &block->chain_list, list) - tcf_chain_hold(chain); - - list_for_each_entry(chain, &block->chain_list, list) - tcf_chain_flush(chain); - } - + if (!free_block) + tcf_block_flush_all_chains(block); tcf_block_offload_unbind(block, q, ei); - if (free_block) { + if (free_block) kfree(block); - } else { - /* At this point, all the chains should have - * refcnt >= 1. - */ - list_for_each_entry_safe(chain, tmp, &block->chain_list, - list) { - tcf_chain_put_explicitly_created(chain); - tcf_chain_put(chain); - } - } + else + tcf_block_put_all_chains(block); } else { tcf_block_offload_unbind(block, q, ei); } -- 2.7.5