| .. | .. |
|---|
| 41 | 41 | #include <net/tc_act/tc_gate.h> |
|---|
| 42 | 42 | #include <net/flow_offload.h> |
|---|
| 43 | 43 | |
|---|
| 44 | | -extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1]; |
|---|
| 45 | | - |
|---|
| 46 | 44 | /* The list of all installed classifier types */ |
|---|
| 47 | 45 | static LIST_HEAD(tcf_proto_base); |
|---|
| 48 | 46 | |
|---|
| .. | .. |
|---|
| 535 | 533 | { |
|---|
| 536 | 534 | struct tcf_block *block = chain->block; |
|---|
| 537 | 535 | const struct tcf_proto_ops *tmplt_ops; |
|---|
| 536 | + unsigned int refcnt, non_act_refcnt; |
|---|
| 538 | 537 | bool free_block = false; |
|---|
| 539 | | - unsigned int refcnt; |
|---|
| 540 | 538 | void *tmplt_priv; |
|---|
| 541 | 539 | |
|---|
| 542 | 540 | mutex_lock(&block->lock); |
|---|
| .. | .. |
|---|
| 556 | 554 | * save these to temporary variables. |
|---|
| 557 | 555 | */ |
|---|
| 558 | 556 | refcnt = --chain->refcnt; |
|---|
| 557 | + non_act_refcnt = refcnt - chain->action_refcnt; |
|---|
| 559 | 558 | tmplt_ops = chain->tmplt_ops; |
|---|
| 560 | 559 | tmplt_priv = chain->tmplt_priv; |
|---|
| 561 | 560 | |
|---|
| 562 | | - /* The last dropped non-action reference will trigger notification. */ |
|---|
| 563 | | - if (refcnt - chain->action_refcnt == 0 && !by_act) { |
|---|
| 564 | | - tc_chain_notify_delete(tmplt_ops, tmplt_priv, chain->index, |
|---|
| 565 | | - block, NULL, 0, 0, false); |
|---|
| 561 | + if (non_act_refcnt == chain->explicitly_created && !by_act) { |
|---|
| 562 | + if (non_act_refcnt == 0) |
|---|
| 563 | + tc_chain_notify_delete(tmplt_ops, tmplt_priv, |
|---|
| 564 | + chain->index, block, NULL, 0, 0, |
|---|
| 565 | + false); |
|---|
| 566 | 566 | /* Last reference to chain, no need to lock. */ |
|---|
| 567 | 567 | chain->flushing = false; |
|---|
| 568 | 568 | } |
|---|
| .. | .. |
|---|
| 1466 | 1466 | |
|---|
| 1467 | 1467 | err_unroll: |
|---|
| 1468 | 1468 | list_for_each_entry_safe(block_cb, next, &bo->cb_list, list) { |
|---|
| 1469 | + list_del(&block_cb->driver_list); |
|---|
| 1469 | 1470 | if (i-- > 0) { |
|---|
| 1470 | 1471 | list_del(&block_cb->list); |
|---|
| 1471 | 1472 | tcf_block_playback_offloads(block, block_cb->cb, |
|---|
| .. | .. |
|---|
| 2773 | 2774 | return PTR_ERR(ops); |
|---|
| 2774 | 2775 | if (!ops->tmplt_create || !ops->tmplt_destroy || !ops->tmplt_dump) { |
|---|
| 2775 | 2776 | NL_SET_ERR_MSG(extack, "Chain templates are not supported with specified classifier"); |
|---|
| 2777 | + module_put(ops->owner); |
|---|
| 2776 | 2778 | return -EOPNOTSUPP; |
|---|
| 2777 | 2779 | } |
|---|
| 2778 | 2780 | |
|---|