On Wed 31 Mar 2021 at 07:40, Cong Wang <xiyou.wangc...@gmail.com> wrote: > On Mon, Mar 29, 2021 at 3:55 PM Kumar Kartikeya Dwivedi > <mem...@gmail.com> wrote: >> diff --git a/net/sched/act_api.c b/net/sched/act_api.c >> index b919826939e0..43cceb924976 100644 >> --- a/net/sched/act_api.c >> +++ b/net/sched/act_api.c >> @@ -1042,6 +1042,9 @@ struct tc_action *tcf_action_init_1(struct net *net, >> struct tcf_proto *tp, >> if (err != ACT_P_CREATED) >> module_put(a_o->owner); >> >> + if (!bind && ovr && err == ACT_P_CREATED) >> + refcount_set(&a->tcfa_refcnt, 2); >> + > > Hmm, if we set the refcnt to 2 here, how could tcf_action_destroy() > destroy them when we rollback from a failure in the middle of the loop > in tcf_action_init()? > > Thanks.
Hmm, you might be right. Also, the error handling code in tcf_action_init() looks incorrect: err: tcf_action_destroy(actions, bind); err_mod: for (i = 0; i < TCA_ACT_MAX_PRIO; i++) { if (ops[i]) module_put(ops[i]->owner); } return err; It looks like here the modules for all actions that successfully completed their init has already been release by either tcf_action_init_1() on action overwrite or by tcf_action_destroy() on action create. I'll try to come up with tests that validate these corner cases. Regards, Vlad