[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230801113807.85473-7-jhs@mojatatu.com>
Date: Tue, 1 Aug 2023 07:37:50 -0400
From: Jamal Hadi Salim <jhs@...atatu.com>
To: netdev@...r.kernel.org
Cc: deb.chatterjee@...el.com,
anjali.singhai@...el.com,
namrata.limaye@...el.com,
tom@...anda.io,
mleitner@...hat.com,
Mahesh.Shirshyad@....com,
Vipin.Jain@....com,
tomasz.osinski@...el.com,
jiri@...nulli.us,
xiyou.wangcong@...il.com,
davem@...emloft.net,
edumazet@...gle.com,
kuba@...nel.org,
pabeni@...hat.com,
vladbu@...dia.com,
simon.horman@...igine.com,
khalidm@...dia.com,
toke@...hat.com,
mattyk@...dia.com,
john.andy.fingerhut@...el.com
Subject: [PATCH RFC v5 net-next 06/23] net: sched: act_api: Add support for preallocated dynamic action instances
In P4, actions are assumed to pre exist and have an upper bound number of
instances.
Add the necessary code to preallocate actions instances for dynamic actions.
We add 2 new actions flags:
- TCA_ACT_FLAGS_PREALLOC: Which tells if the actions instance was
preallocated.
- TCA_ACT_FLAGS_UNUSED: Which tells if the actions instance was
preallocated but not used yet.
The rule is that preallocated actions can't be deleted by the tc actions
runtime commands and a dump or a get will only show preallocated actions
instances which are being used (TCA_ACT_FLAGS_UNUSED == false).
The preallocated actions will be deleted once the dynamic action kind to
which they belong to is deleted.
Co-developed-by: Victor Nogueira <victor@...atatu.com>
Signed-off-by: Victor Nogueira <victor@...atatu.com>
Co-developed-by: Pedro Tammela <pctammela@...atatu.com>
Signed-off-by: Pedro Tammela <pctammela@...atatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@...atatu.com>
---
include/net/act_api.h | 3 +++
net/sched/act_api.c | 46 ++++++++++++++++++++++++++++++++-----------
2 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/include/net/act_api.h b/include/net/act_api.h
index b83e058a3..a6331cc5d 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -68,6 +68,8 @@ struct tc_action {
#define TCA_ACT_FLAGS_REPLACE (1U << (TCA_ACT_FLAGS_USER_BITS + 2))
#define TCA_ACT_FLAGS_NO_RTNL (1U << (TCA_ACT_FLAGS_USER_BITS + 3))
#define TCA_ACT_FLAGS_AT_INGRESS (1U << (TCA_ACT_FLAGS_USER_BITS + 4))
+#define TCA_ACT_FLAGS_PREALLOC (1U << (TCA_ACT_FLAGS_USER_BITS + 5))
+#define TCA_ACT_FLAGS_UNUSED (1U << (TCA_ACT_FLAGS_USER_BITS + 6))
/* Update lastuse only if needed, to avoid dirtying a cache line.
* We use a temp variable to avoid fetching jiffies twice.
@@ -202,6 +204,7 @@ int tcf_idr_create_from_flags(struct tc_action_net *tn, u32 index,
const struct tc_action_ops *ops, int bind,
u32 flags);
void tcf_idr_insert_many(struct tc_action *actions[]);
+void tcf_idr_insert_n(struct tc_action *actions[], const u32 n);
void tcf_idr_cleanup(struct tc_action_net *tn, u32 index);
int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index,
struct tc_action **a, int bind);
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 3ce586331..bc9fab75b 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -560,6 +560,8 @@ static int tcf_dump_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
continue;
if (IS_ERR(p))
continue;
+ if (p->tcfa_flags & TCA_ACT_FLAGS_UNUSED)
+ continue;
if (jiffy_since &&
time_after(jiffy_since,
@@ -640,6 +642,9 @@ static int tcf_del_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
idr_for_each_entry_ul(idr, p, tmp, id) {
if (IS_ERR(p))
continue;
+ if (p->tcfa_flags & TCA_ACT_FLAGS_PREALLOC)
+ continue;
+
ret = tcf_idr_release_unsafe(p);
if (ret == ACT_P_DELETED)
module_put(ops->owner);
@@ -1367,26 +1372,38 @@ static const struct nla_policy tcf_action_policy[TCA_ACT_MAX + 1] = {
[TCA_ACT_HW_STATS] = NLA_POLICY_BITFIELD32(TCA_ACT_HW_STATS_ANY),
};
+static void tcf_idr_insert_1(struct tc_action *a)
+{
+ struct tcf_idrinfo *idrinfo;
+
+ idrinfo = a->idrinfo;
+ mutex_lock(&idrinfo->lock);
+ /* Replace ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc if
+ * it is just created, otherwise this is just a nop.
+ */
+ idr_replace(&idrinfo->action_idr, a, a->tcfa_index);
+ mutex_unlock(&idrinfo->lock);
+}
+
void tcf_idr_insert_many(struct tc_action *actions[])
{
int i;
for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
- struct tc_action *a = actions[i];
- struct tcf_idrinfo *idrinfo;
-
- if (!a)
+ if (!actions[i])
continue;
- idrinfo = a->idrinfo;
- mutex_lock(&idrinfo->lock);
- /* Replace ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc if
- * it is just created, otherwise this is just a nop.
- */
- idr_replace(&idrinfo->action_idr, a, a->tcfa_index);
- mutex_unlock(&idrinfo->lock);
+ tcf_idr_insert_1(actions[i]);
}
}
+void tcf_idr_insert_n(struct tc_action *actions[], const u32 n)
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ tcf_idr_insert_1(actions[i]);
+}
+
struct tc_action_ops *tc_action_load_ops(struct net *net, struct nlattr *nla,
bool police, bool rtnl_held,
struct netlink_ext_ack *extack)
@@ -2033,6 +2050,13 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
ret = PTR_ERR(act);
goto err;
}
+ if (event == RTM_DELACTION &&
+ act->tcfa_flags & TCA_ACT_FLAGS_PREALLOC) {
+ ret = -EINVAL;
+ NL_SET_ERR_MSG_FMT(extack,
+ "Unable to delete preallocated action %s\n",
+ act->ops->kind);
+ }
attr_size += tcf_action_fill_size(act);
actions[i - 1] = act;
}
--
2.34.1
Powered by blists - more mailing lists