Skip to content

Commit 1dd7f18

Browse files
tammelakuba-moo
authored andcommitted
net/sched: act_api: skip idr replace on bound actions
tcf_idr_insert_many will replace the allocated -EBUSY pointer in tcf_idr_check_alloc with the real action pointer, exposing it to all operations. This operation is only needed when the action pointer is created (ACT_P_CREATED). For actions which are bound to (returned 0), the pointer already resides in the idr making such operation a nop. Even though it's a nop, it's still not a cheap operation as internally the idr code walks the idr and then does a replace on the appropriate slot. So if the action was bound, better skip the idr replace entirely. Signed-off-by: Pedro Tammela <[email protected]> Acked-by: Jamal Hadi Salim <[email protected]> Reviewed-by: Vlad Buslov <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 4b55e86 commit 1dd7f18

File tree

3 files changed

+8
-7
lines changed

3 files changed

+8
-7
lines changed

include/net/act_api.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ int tcf_idr_create_from_flags(struct tc_action_net *tn, u32 index,
191191
struct nlattr *est, struct tc_action **a,
192192
const struct tc_action_ops *ops, int bind,
193193
u32 flags);
194-
void tcf_idr_insert_many(struct tc_action *actions[]);
194+
void tcf_idr_insert_many(struct tc_action *actions[], int init_res[]);
195195
void tcf_idr_cleanup(struct tc_action_net *tn, u32 index);
196196
int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index,
197197
struct tc_action **a, int bind);

net/sched/act_api.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,19 +1304,20 @@ static const struct nla_policy tcf_action_policy[TCA_ACT_MAX + 1] = {
13041304
[TCA_ACT_HW_STATS] = NLA_POLICY_BITFIELD32(TCA_ACT_HW_STATS_ANY),
13051305
};
13061306

1307-
void tcf_idr_insert_many(struct tc_action *actions[])
1307+
void tcf_idr_insert_many(struct tc_action *actions[], int init_res[])
13081308
{
13091309
struct tc_action *a;
13101310
int i;
13111311

13121312
tcf_act_for_each_action(i, a, actions) {
13131313
struct tcf_idrinfo *idrinfo;
13141314

1315+
if (init_res[i] == 0) /* Bound */
1316+
continue;
1317+
13151318
idrinfo = a->idrinfo;
13161319
mutex_lock(&idrinfo->lock);
1317-
/* Replace ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc if
1318-
* it is just created, otherwise this is just a nop.
1319-
*/
1320+
/* Replace ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc */
13201321
idr_replace(&idrinfo->action_idr, a, a->tcfa_index);
13211322
mutex_unlock(&idrinfo->lock);
13221323
}
@@ -1516,7 +1517,7 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
15161517
/* We have to commit them all together, because if any error happened in
15171518
* between, we could not handle the failure gracefully.
15181519
*/
1519-
tcf_idr_insert_many(actions);
1520+
tcf_idr_insert_many(actions, init_res);
15201521

15211522
*attr_size = tcf_action_full_attrs_size(sz);
15221523
err = i - 1;

net/sched/cls_api.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3313,7 +3313,7 @@ int tcf_exts_validate_ex(struct net *net, struct tcf_proto *tp, struct nlattr **
33133313
act->type = exts->type = TCA_OLD_COMPAT;
33143314
exts->actions[0] = act;
33153315
exts->nr_actions = 1;
3316-
tcf_idr_insert_many(exts->actions);
3316+
tcf_idr_insert_many(exts->actions, init_res);
33173317
} else if (exts->action && tb[exts->action]) {
33183318
int err;
33193319

0 commit comments

Comments
 (0)