hi Vlad,
On Mon, 2019-02-18 at 16:52 +0000, Vlad Buslov wrote:
> Hi Davide,
>
> I really like the idea of putting all action validation code in single
> place, instead of spreading it between act API and specific actions init
> code.
sure, the previous validation code was in tcf_action_add_1(), and I
attempted to fix the problems (well, it's the same problem showing up in
3 different ways) without adding the same code everywhere.
Sadly, we need to handle correctly the situations where
tcf_action_check_ctrlact() returns an error, and I'm seeing that we
can't fix every action with the same exact code everywhere (to avoid
leaking IDRs, or memory, or both).
> See my comment regarding minor problem with using
> tcf_action_set_ctrlact() on current net-next below.
> > +void tcf_action_set_ctrlact(struct tc_action *p, int action,
> > + struct tcf_chain *goto_chain)
> > +{
> > + struct tcf_chain *old;
> > +
> > + old = xchg(&p->goto_chain, goto_chain);
> > + if (old)
> > + tcf_chain_put_by_act(old);
>
> This is blocking in current net-next because tcf_chain_put_by_act()
> obtains block->lock mutex, so you can't call it while holding tcf_lock
> spinlock like you do in following patches. Its not a big problem but
> I guess you will have to just inline this code into all init handlers
> instead of tcf_action_set_ctrlact() function.
Argh! you are right. Thanks a lot for spotting this.
Ok, let's kill tcf_action_set_ctrlact() and swap 'newchain' with
a->goto_chain in each action init(), with a->tcfa_lock taken. I will
then call tcf_chain_put_by_act() in the init() handler, after the
spinlock is released.
> BTW is atomic xchg strictly necessary if you hold tcf_lock while
> re-assigning goto_chain pointer?
No, it's not necessary. The new value of goto_chain is used only when the
new value of tcfa_action is updated: so, if we just do the assignment of
goto_chain and tcfa_action together with the spinlock taken, at least we
are improving the
current code.
Thanks!
--
davide