From patchwork Tue Jul 31 12:07:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 951577 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="Hq8Te4D9"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41fwHx1Y67z9s2g for ; Tue, 31 Jul 2018 22:10:37 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732048AbeGaNug (ORCPT ); Tue, 31 Jul 2018 09:50:36 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:38061 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731863AbeGaNuf (ORCPT ); Tue, 31 Jul 2018 09:50:35 -0400 Received: by mail-wr1-f67.google.com with SMTP id v14-v6so16405772wro.5 for ; Tue, 31 Jul 2018 05:10:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/X++bCllyIlMY68cTqfxqVkvQTBKyEE1Kjie45Tm988=; b=Hq8Te4D9ZJqXxysXgCPmDyQLhpj+WylBYFTtNjgwnH3boqAm3qdelvMTmEu1Tyw3yn C9vCnWKc6epRijDuUmh5I5CYZOCwmp8A+dcNJND2x4wHVqmP8Rd2enlW3wHUfjncJP3c JojKecDnzgpDCqVvvcIv0w48jiuwqdXCEzIzb9bL8kQyYHSHbuNeMsLCWlBrLlm5QUx+ SiHp9lAgdkhWPBFxwiDMzn9EuYlyRk8DBcElCCZ6RxhLi6vxkGJDaQkgl/2dG7Yp0UFy okoeSiyo0Tam8xazBojwQCh8BwLLHMGszJaquSfNy+ucklxC2K7QwFVybVwWBH/rPH70 0PXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/X++bCllyIlMY68cTqfxqVkvQTBKyEE1Kjie45Tm988=; b=Yx6KAa2BKuq7uW30Orc/MbW8AyJTsgKa60BRPeoozt/C+rZM5DzGlsSGU+Uqfpmt3X Kq6Jz0HUUnNGvcDtCE+iQLlS0du3jh38s7KqHEjQ6xaaINGzu8HH5URgi0lpO1L3xoYW z93mKauRBAVpPQvNNAOCl+XtvjoTfzolNSc6X7h83BMJrsYU8P3AGVektr4ESYR3NHvY WfuvmRZe11sQQQ+oY3JMXCjwQkSGi7yviaQN2wXuclEmcdJNRdi6tlroWaMI47AeAWTi B2L9t3MuQqSgy6bVBDTfJzp7ImKe64uwtgHgH2OwkYDqeCep9YCrlYhMpzr7H53gyt+V Obwg== X-Gm-Message-State: AOUpUlE2VXK0HMBVxyx3FIlCKs6MpFy+SEAKli6/3NcXQEIBeqUwPaOG DVb4g9e4WuPdsK6uHXFfrjDi+8uGt4m42w== X-Google-Smtp-Source: AAOMgpdCjgYBlP/P2DPey5hzQGDicm8NdmkHwQ5kSxh6vfnLRYnXy18T0ZC1QBCsywfRI8KaEtczHQ== X-Received: by 2002:adf:9485:: with SMTP id 5-v6mr21753337wrr.82.1533039031644; Tue, 31 Jul 2018 05:10:31 -0700 (PDT) Received: from localhost (static-cl188134168102.unet.cz. [188.134.168.102]) by smtp.gmail.com with ESMTPSA id k12-v6sm5461231wru.38.2018.07.31.05.10.31 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 31 Jul 2018 05:10:31 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jakub.kicinski@netronome.com, mlxsw@mellanox.com Subject: [patch net-next 2/2] net: sched: fix notifications for action-held chains Date: Tue, 31 Jul 2018 14:07:45 +0200 Message-Id: <20180731120745.1230-3-jiri@resnulli.us> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180731120745.1230-1-jiri@resnulli.us> References: <20180731120745.1230-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko Chains that only have action references serve as placeholders. Until a non-action reference is created, user should not be aware of the chain. Also he should not receive any notifications about it. So send notifications for the new chain only in case the chain gets the first non-action reference. Symmetrically to that, when the last non-action reference is dropped, send the notification about deleted chain. Reported-by: Cong Wang Signed-off-by: Jiri Pirko Acked-by: Cong Wang --- net/sched/cls_api.c | 70 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 2f78341f2888..ac9b4148878d 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -262,16 +262,6 @@ static void tcf_chain_hold(struct tcf_chain *chain) ++chain->refcnt; } -static void tcf_chain_hold_by_act(struct tcf_chain *chain) -{ - ++chain->action_refcnt; -} - -static void tcf_chain_release_by_act(struct tcf_chain *chain) -{ - --chain->action_refcnt; -} - static bool tcf_chain_held_by_acts_only(struct tcf_chain *chain) { /* In case all the references are action references, this @@ -295,52 +285,76 @@ static struct tcf_chain *tcf_chain_lookup(struct tcf_block *block, static int tc_chain_notify(struct tcf_chain *chain, struct sk_buff *oskb, u32 seq, u16 flags, int event, bool unicast); -struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index, - bool create) +struct tcf_chain *__tcf_chain_get(struct tcf_block *block, u32 chain_index, + bool create, bool by_act) { struct tcf_chain *chain = tcf_chain_lookup(block, chain_index); if (chain) { tcf_chain_hold(chain); - return chain; + } else { + if (!create) + return NULL; + chain = tcf_chain_create(block, chain_index); + if (!chain) + return NULL; } - if (!create) - return NULL; - chain = tcf_chain_create(block, chain_index); - if (!chain) - return NULL; - tc_chain_notify(chain, NULL, 0, NLM_F_CREATE | NLM_F_EXCL, - RTM_NEWCHAIN, false); + if (by_act) + ++chain->action_refcnt; + + /* Send notification only in case we got the first + * non-action reference. Until then, the chain acts only as + * a placeholder for actions pointing to it and user ought + * not know about them. + */ + if (chain->refcnt - chain->action_refcnt == 1 && !by_act) + tc_chain_notify(chain, NULL, 0, NLM_F_CREATE | NLM_F_EXCL, + RTM_NEWCHAIN, false); + return chain; } + +struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index, + bool create) +{ + return __tcf_chain_get(block, chain_index, create, false); +} EXPORT_SYMBOL(tcf_chain_get); struct tcf_chain *tcf_chain_get_by_act(struct tcf_block *block, u32 chain_index) { - struct tcf_chain *chain = tcf_chain_get(block, chain_index, true); - - tcf_chain_hold_by_act(chain); - return chain; + return __tcf_chain_get(block, chain_index, true, true); } EXPORT_SYMBOL(tcf_chain_get_by_act); static void tc_chain_tmplt_del(struct tcf_chain *chain); -void tcf_chain_put(struct tcf_chain *chain) +void __tcf_chain_put(struct tcf_chain *chain, bool by_act) { - if (--chain->refcnt == 0) { + if (by_act) + chain->action_refcnt--; + chain->refcnt--; + + /* The last dropped non-action reference will trigger notification. */ + if (chain->refcnt - chain->action_refcnt == 0 && !by_act) tc_chain_notify(chain, NULL, 0, 0, RTM_DELCHAIN, false); + + if (chain->refcnt == 0) { tc_chain_tmplt_del(chain); tcf_chain_destroy(chain); } } + +void tcf_chain_put(struct tcf_chain *chain) +{ + __tcf_chain_put(chain, false); +} EXPORT_SYMBOL(tcf_chain_put); void tcf_chain_put_by_act(struct tcf_chain *chain) { - tcf_chain_release_by_act(chain); - tcf_chain_put(chain); + __tcf_chain_put(chain, true); } EXPORT_SYMBOL(tcf_chain_put_by_act);