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