Message ID | 20211013211000.8962-1-pmenzel@molgen.mpg.de (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net: sched: fix infinite loop when trying to create tcf rule | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Single patches do not need cover letters |
netdev/fixes_present | success | Fixes tag not required for -next series |
netdev/patch_count | success | Link |
netdev/tree_selection | success | Guessed tree name to be net-next |
netdev/subject_prefix | warning | Target tree name not specified in the subject |
netdev/cc_maintainers | success | CCed 6 of 6 maintainers |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Signed-off-by tag matches author and committer |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | success | Errors and warnings before: 8 this patch: 8 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | No Fixes tag |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 17 lines checked |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 8 this patch: 8 |
netdev/header_inline | success | No static functions without inline keyword in header files |
On Wed, 13 Oct 2021 23:09:59 +0200 Paul Menzel wrote: > From: Serhiy Boiko <serhiy.boiko@plvision.eu> > > After running a specific set of commands tc will become unresponsive: > > $ ip link add dev DEV type veth > $ tc qdisc add dev DEV clsact > $ tc chain add dev DEV chain 0 ingress > $ tc filter del dev DEV ingress > $ tc filter add dev DEV ingress flower action pass > > When executing chain flush the chain->flushing field is set to true, which > prevents insertion of new classifier instances. It is unset in one place > under two conditions: `refcnt - chain->action_refcnt == 0` and `!by_act`. > Ignoring the by_act and action_refcnt arguments the `flushing procedure` > will be over when refcnt is 0. > > But if the chain is explicitly created (e.g. `tc chain add .. chain 0 ..`) > refcnt is set to 1 without any classifier instances. Thus the condition is > never met and the chain->flushing field is never cleared. And because the > default chain is `flushing` new classifiers cannot be added. tc_new_tfilter > is stuck in a loop trying to find a chain where chain->flushing is false. > > Moving `chain->flushing = false` from __tcf_chain_put to the end of > tcf_chain_flush will avoid the condition and the field will always be reset > after the flush procedure. > > Signed-off-by: Serhiy Boiko <serhiy.boiko@plvision.eu> > [Upstreamed from https://github.com/dentproject/dentOS/commit/3480aceaa5244a11edfe1fda90afd92b0199ef23] > Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de> This had already been submitted: https://lore.kernel.org/all/1633848948-11315-1-git-send-email-volodymyr.mytnyk@plvision.eu/
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 2ef8f5a6205a..405f955bef1e 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -563,8 +563,6 @@ static void __tcf_chain_put(struct tcf_chain *chain, bool by_act, if (refcnt - chain->action_refcnt == 0 && !by_act) { tc_chain_notify_delete(tmplt_ops, tmplt_priv, chain->index, block, NULL, 0, 0, false); - /* Last reference to chain, no need to lock. */ - chain->flushing = false; } if (refcnt == 0) @@ -615,6 +613,9 @@ static void tcf_chain_flush(struct tcf_chain *chain, bool rtnl_held) tcf_proto_put(tp, rtnl_held, NULL); tp = tp_next; } + + /* Last reference to chain, no need to lock. */ + chain->flushing = false; } static int tcf_block_setup(struct tcf_block *block,