Call it on tcf_block_cb object to release the private area. Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- include/net/pkt_cls.h | 3 ++- net/sched/cls_api.c | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index d40fcd8c502b..52a6484428ce 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -72,7 +72,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); void tcf_block_cb_list_add(struct tcf_block_cb *block_cb, struct list_head *cb_list); void tcf_block_cb_list_move(struct tcf_block_cb *block_cb, struct list_head *cb_list); diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 3c16ac802dc4..963511ec758d 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -711,6 +711,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; @@ -753,7 +754,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; @@ -763,6 +765,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; @@ -771,6 +774,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); @@ -804,7 +810,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 (!block_cb) return ERR_PTR(-ENOMEM); -- 2.11.0