hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/lib/once.c
....@@ -3,12 +3,10 @@
33 #include <linux/spinlock.h>
44 #include <linux/once.h>
55 #include <linux/random.h>
6
-#include <linux/module.h>
76
87 struct once_work {
98 struct work_struct work;
109 struct static_key_true *key;
11
- struct module *module;
1210 };
1311
1412 static void once_deferred(struct work_struct *w)
....@@ -18,11 +16,10 @@
1816 work = container_of(w, struct once_work, work);
1917 BUG_ON(!static_key_enabled(work->key));
2018 static_branch_disable(work->key);
21
- module_put(work->module);
2219 kfree(work);
2320 }
2421
25
-static void once_disable_jump(struct static_key_true *key, struct module *mod)
22
+static void once_disable_jump(struct static_key_true *key)
2623 {
2724 struct once_work *w;
2825
....@@ -32,8 +29,6 @@
3229
3330 INIT_WORK(&w->work, once_deferred);
3431 w->key = key;
35
- w->module = mod;
36
- __module_get(mod);
3732 schedule_work(&w->work);
3833 }
3934
....@@ -58,11 +53,41 @@
5853 EXPORT_SYMBOL(__do_once_start);
5954
6055 void __do_once_done(bool *done, struct static_key_true *once_key,
61
- unsigned long *flags, struct module *mod)
56
+ unsigned long *flags)
6257 __releases(once_lock)
6358 {
6459 *done = true;
6560 spin_unlock_irqrestore(&once_lock, *flags);
66
- once_disable_jump(once_key, mod);
61
+ once_disable_jump(once_key);
6762 }
6863 EXPORT_SYMBOL(__do_once_done);
64
+
65
+static DEFINE_MUTEX(once_mutex);
66
+
67
+bool __do_once_slow_start(bool *done)
68
+ __acquires(once_mutex)
69
+{
70
+ mutex_lock(&once_mutex);
71
+ if (*done) {
72
+ mutex_unlock(&once_mutex);
73
+ /* Keep sparse happy by restoring an even lock count on
74
+ * this mutex. In case we return here, we don't call into
75
+ * __do_once_done but return early in the DO_ONCE_SLOW() macro.
76
+ */
77
+ __acquire(once_mutex);
78
+ return false;
79
+ }
80
+
81
+ return true;
82
+}
83
+EXPORT_SYMBOL(__do_once_slow_start);
84
+
85
+void __do_once_slow_done(bool *done, struct static_key_true *once_key,
86
+ struct module *mod)
87
+ __releases(once_mutex)
88
+{
89
+ *done = true;
90
+ mutex_unlock(&once_mutex);
91
+ once_disable_jump(once_key);
92
+}
93
+EXPORT_SYMBOL(__do_once_slow_done);