If we do add the destructor hook, I think it looks like this. It would merit some write-up in utrace.tmpl text too.
I'm not especially convinced it's a very good idea. But I won't object if people serious about using the API think it helps. Thanks, Roland --- include/linux/utrace.h | 8 ++++++++ kernel/utrace.c | 3 +++ 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/include/linux/utrace.h b/include/linux/utrace.h index c19c01b..f968792 100644 --- a/include/linux/utrace.h +++ b/include/linux/utrace.h @@ -322,6 +322,7 @@ static inline enum utrace_syscall_action utrace_syscall_action(u32 action) struct utrace_engine { /* private: */ struct kref kref; + void (*release)(void *); struct list_head entry; /* public: */ @@ -539,6 +540,12 @@ static inline void utrace_engine_put(struct utrace_engine *engine) * Unlike other callbacks, this can be called from the parent's context * rather than from the traced thread itself--it must not delay the * parent by blocking. + * + * @release: + * If not %NULL, this is called after the last utrace_engine_put() + * call for a &struct utrace_engine, which could be implicit after + * a %UTRACE_DETACH return from another callback. Its argument is + * the engine's @data member. */ struct utrace_engine_ops { u32 (*report_quiesce)(enum utrace_resume_action action, @@ -584,6 +591,7 @@ struct utrace_engine_ops { bool group_dead, int signal); void (*report_reap)(struct utrace_engine *engine, struct task_struct *task); + void (*release)(void *data); }; /** diff --git a/kernel/utrace.c b/kernel/utrace.c index 35be909..3b7ac74 100644 --- a/kernel/utrace.c +++ b/kernel/utrace.c @@ -79,6 +79,8 @@ void __utrace_engine_release(struct kref *kref) struct utrace_engine *engine = container_of(kref, struct utrace_engine, kref); BUG_ON(!list_empty(&engine->entry)); + if (engine->release) + (*engine->release)(engine->data); kmem_cache_free(utrace_engine_cachep, engine); } EXPORT_SYMBOL_GPL(__utrace_engine_release); @@ -271,6 +273,7 @@ struct utrace_engine *utrace_attach_task( engine->flags = 0; engine->ops = ops; engine->data = data; + engine->release = ops->release; ret = utrace_attach_delay(target); if (likely(!ret))