Extend struct task_struct with a blog_contexts array to hold per-module BLOG TLS pointers. Each task may have up to BLOG_MAX_MODULES (currently 8) distinct logging contexts, allowing multiple subsystems to attach binary loggers without interference. The fork path (copy_process) initializes blog_contexts to NULL for new tasks, ensuring clean initial state. The exit path (do_exit) calls blog_tls_clear_task() to release any active contexts before task teardown, ensuring contexts are properly recycled to the magazine pool and preventing use-after-free scenarios. These changes are conditional on CONFIG_BLOG. Kernels built without BLOG support incur no storage or runtime overhead in task_struct. This commit establishes the foundation for per-task binary logging contexts but does not activate any logging functionality. The BLOG subsystem itself is introduced in subsequent commits. Signed-off-by: Alex Markuze --- include/linux/sched.h | 7 +++++++ kernel/fork.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/linux/sched.h b/include/linux/sched.h index 07576479c0ed..e381f8421a11 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1278,6 +1278,13 @@ struct task_struct { /* Journalling filesystem info: */ void *journal_info; +/* BLOG support - max modules defined here for use by other headers */ +#define BLOG_MAX_MODULES 8 + +#ifdef CONFIG_BLOG + struct blog_tls_ctx *blog_contexts[BLOG_MAX_MODULES]; +#endif + /* Stacked block device info: */ struct bio_list *bio_list; diff --git a/kernel/fork.c b/kernel/fork.c index 3da0f08615a9..b06843af05a9 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -24,6 +24,9 @@ #include #include #include +#ifdef CONFIG_BLOG +#include +#endif #include #include #include @@ -186,6 +189,29 @@ static inline struct task_struct *alloc_task_struct_node(int node) static inline void free_task_struct(struct task_struct *tsk) { +#ifdef CONFIG_BLOG + /* Clean up any BLOG contexts */ + { + struct blog_tls_ctx *contexts[BLOG_MAX_MODULES]; + int i; + + /* Step 1: Atomically detach all contexts while holding lock */ + task_lock(tsk); + for (i = 0; i < BLOG_MAX_MODULES; i++) { + contexts[i] = tsk->blog_contexts[i]; + tsk->blog_contexts[i] = NULL; + } + task_unlock(tsk); + + /* Step 2: Release contexts outside the lock */ + for (i = 0; i < BLOG_MAX_MODULES; i++) { + struct blog_tls_ctx *ctx = contexts[i]; + + if (ctx && ctx->release) + ctx->release(ctx); + } + } +#endif kmem_cache_free(task_struct_cachep, tsk); } @@ -2012,6 +2038,17 @@ __latent_entropy struct task_struct *copy_process( p = dup_task_struct(current, node); if (!p) goto fork_out; + +#ifdef CONFIG_BLOG + /* Initialize BLOG contexts */ + { + int i; + + for (i = 0; i < BLOG_MAX_MODULES; i++) + p->blog_contexts[i] = NULL; + } +#endif + p->flags &= ~PF_KTHREAD; if (args->kthread) p->flags |= PF_KTHREAD; -- 2.34.1