From: Jiri Pirko <jiri@resnulli.us>
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 v2 2/3] net: sched: fix notifications for action-held chains
Date: Wed, 1 Aug 2018 12:36:56 +0200 [thread overview]
Message-ID: <20180801103657.10532-3-jiri@resnulli.us> (raw)
In-Reply-To: <20180801103657.10532-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
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 <xiyou.wangcong@gmail.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
v1->v2:
- made __tcf_chain_{get,put}() static as suggested by Cong
---
net/sched/cls_api.c | 71 ++++++++++++++++++++++++++++++++---------------------
1 file changed, 43 insertions(+), 28 deletions(-)
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 2f78341f2888..b194a5abfc6a 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,77 @@ 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)
+static 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)
+static 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);
--
2.14.4
next prev parent reply other threads:[~2018-08-01 12:22 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-01 10:36 [patch net-next v2 0/3] net: sched: couple of adjustments/fixes Jiri Pirko
2018-08-01 10:36 ` [patch net-next v2 1/3] net: sched: change name of zombie chain to "held_by_acts_only" Jiri Pirko
2018-08-01 10:36 ` Jiri Pirko [this message]
2018-08-01 10:36 ` [patch net-next v2 3/3] net: sched: make tcf_chain_{get,put}() static Jiri Pirko
2018-08-01 17:06 ` [patch net-next v2 0/3] net: sched: couple of adjustments/fixes David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180801103657.10532-3-jiri@resnulli.us \
--to=jiri@resnulli.us \
--cc=davem@davemloft.net \
--cc=jakub.kicinski@netronome.com \
--cc=jhs@mojatatu.com \
--cc=mlxsw@mellanox.com \
--cc=netdev@vger.kernel.org \
--cc=xiyou.wangcong@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).