From 102a0743326a03cd1a1202ceda21e175b7d3575c Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Tue, 20 Feb 2024 01:20:52 +0000 Subject: [PATCH] add new system file --- kernel/lib/once.c | 41 +++++++++++++++++++++++++++++++++-------- 1 files changed, 33 insertions(+), 8 deletions(-) diff --git a/kernel/lib/once.c b/kernel/lib/once.c index 59149bf..1b71cd7 100644 --- a/kernel/lib/once.c +++ b/kernel/lib/once.c @@ -3,12 +3,10 @@ #include <linux/spinlock.h> #include <linux/once.h> #include <linux/random.h> -#include <linux/module.h> struct once_work { struct work_struct work; struct static_key_true *key; - struct module *module; }; static void once_deferred(struct work_struct *w) @@ -18,11 +16,10 @@ work = container_of(w, struct once_work, work); BUG_ON(!static_key_enabled(work->key)); static_branch_disable(work->key); - module_put(work->module); kfree(work); } -static void once_disable_jump(struct static_key_true *key, struct module *mod) +static void once_disable_jump(struct static_key_true *key) { struct once_work *w; @@ -32,8 +29,6 @@ INIT_WORK(&w->work, once_deferred); w->key = key; - w->module = mod; - __module_get(mod); schedule_work(&w->work); } @@ -58,11 +53,41 @@ EXPORT_SYMBOL(__do_once_start); void __do_once_done(bool *done, struct static_key_true *once_key, - unsigned long *flags, struct module *mod) + unsigned long *flags) __releases(once_lock) { *done = true; spin_unlock_irqrestore(&once_lock, *flags); - once_disable_jump(once_key, mod); + once_disable_jump(once_key); } EXPORT_SYMBOL(__do_once_done); + +static DEFINE_MUTEX(once_mutex); + +bool __do_once_slow_start(bool *done) + __acquires(once_mutex) +{ + mutex_lock(&once_mutex); + if (*done) { + mutex_unlock(&once_mutex); + /* Keep sparse happy by restoring an even lock count on + * this mutex. In case we return here, we don't call into + * __do_once_done but return early in the DO_ONCE_SLOW() macro. + */ + __acquire(once_mutex); + return false; + } + + return true; +} +EXPORT_SYMBOL(__do_once_slow_start); + +void __do_once_slow_done(bool *done, struct static_key_true *once_key, + struct module *mod) + __releases(once_mutex) +{ + *done = true; + mutex_unlock(&once_mutex); + once_disable_jump(once_key); +} +EXPORT_SYMBOL(__do_once_slow_done); -- Gitblit v1.6.2