Call it on tcf_block_cb object to release the driver private block area. Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- v2: no changes. include/net/pkt_cls.h | 6 ++++-- net/sched/cls_api.c | 10 ++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index d660cb4fad75..fd0bfb63ab70 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -73,7 +73,8 @@ static inline struct Qdisc *tcf_block_q(struct tcf_block *block) } struct tcf_block_cb *tcf_block_cb_alloc(tc_setup_cb_t *cb, - void *cb_ident, void *cb_priv); + void *cb_ident, void *cb_priv, + void (*release)(void *cb_priv)); void tcf_block_cb_free(struct tcf_block_cb *block_cb); struct tc_block_offload; @@ -161,7 +162,8 @@ void tc_setup_cb_block_unregister(struct tcf_block *block, tc_setup_cb_t *cb, } static inline struct tcf_block_cb * -tcf_block_cb_alloc(tc_setup_cb_t *cb, void *cb_ident, void *cb_priv) +tcf_block_cb_alloc(tc_setup_cb_t *cb, void *cb_ident, void *cb_priv, + void (*release)(void *cb_priv)) { return ERR_PTR(-EOPNOTSUPP); } diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index a2c1258cc8dc..534a545ea51e 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -713,6 +713,7 @@ struct tcf_block_cb { struct list_head global_list; struct list_head list; tc_setup_cb_t *cb; + void (*release)(void *cb_priv); void *cb_ident; void *cb_priv; unsigned int refcnt; @@ -750,7 +751,8 @@ unsigned int tcf_block_cb_decref(struct tcf_block_cb *block_cb) EXPORT_SYMBOL(tcf_block_cb_decref); struct tcf_block_cb *tcf_block_cb_alloc(tc_setup_cb_t *cb, - void *cb_ident, void *cb_priv) + void *cb_ident, void *cb_priv, + void (*release)(void *cb_priv)) { struct tcf_block_cb *block_cb; @@ -760,6 +762,7 @@ struct tcf_block_cb *tcf_block_cb_alloc(tc_setup_cb_t *cb, block_cb->cb = cb; block_cb->cb_ident = cb_ident; + block_cb->release = release; block_cb->cb_priv = cb_priv; return block_cb; @@ -768,6 +771,9 @@ EXPORT_SYMBOL(tcf_block_cb_alloc); void tcf_block_cb_free(struct tcf_block_cb *block_cb) { + if (block_cb->release) + block_cb->release(block_cb->cb_priv); + kfree(block_cb); } EXPORT_SYMBOL(tcf_block_cb_free); @@ -801,7 +807,7 @@ struct tcf_block_cb *__tcf_block_cb_register(struct tcf_block *block, if (err) return ERR_PTR(err); - block_cb = tcf_block_cb_alloc(cb, cb_ident, cb_priv); + block_cb = tcf_block_cb_alloc(cb, cb_ident, cb_priv, NULL); if (IS_ERR(block_cb)) return block_cb; -- 2.11.0