Blame view
lib/once.c
1.36 KB
b24413180 License cleanup: ... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
46234253b net: move net_get... |
2 3 4 5 |
#include <linux/slab.h> #include <linux/spinlock.h> #include <linux/once.h> #include <linux/random.h> |
c90aeb948 once: make helper... |
6 |
struct once_work { |
46234253b net: move net_get... |
7 |
struct work_struct work; |
cf4c950b8 once: switch to n... |
8 |
struct static_key_true *key; |
46234253b net: move net_get... |
9 |
}; |
c90aeb948 once: make helper... |
10 |
static void once_deferred(struct work_struct *w) |
46234253b net: move net_get... |
11 |
{ |
c90aeb948 once: make helper... |
12 |
struct once_work *work; |
46234253b net: move net_get... |
13 |
|
c90aeb948 once: make helper... |
14 |
work = container_of(w, struct once_work, work); |
46234253b net: move net_get... |
15 |
BUG_ON(!static_key_enabled(work->key)); |
cf4c950b8 once: switch to n... |
16 |
static_branch_disable(work->key); |
46234253b net: move net_get... |
17 18 |
kfree(work); } |
cf4c950b8 once: switch to n... |
19 |
static void once_disable_jump(struct static_key_true *key) |
46234253b net: move net_get... |
20 |
{ |
c90aeb948 once: make helper... |
21 |
struct once_work *w; |
46234253b net: move net_get... |
22 23 24 25 |
w = kmalloc(sizeof(*w), GFP_ATOMIC); if (!w) return; |
c90aeb948 once: make helper... |
26 |
INIT_WORK(&w->work, once_deferred); |
46234253b net: move net_get... |
27 28 29 |
w->key = key; schedule_work(&w->work); } |
c90aeb948 once: make helper... |
30 |
static DEFINE_SPINLOCK(once_lock); |
46234253b net: move net_get... |
31 |
|
c90aeb948 once: make helper... |
32 33 34 35 |
bool __do_once_start(bool *done, unsigned long *flags) __acquires(once_lock) { spin_lock_irqsave(&once_lock, *flags); |
46234253b net: move net_get... |
36 |
if (*done) { |
c90aeb948 once: make helper... |
37 38 39 40 41 42 |
spin_unlock_irqrestore(&once_lock, *flags); /* Keep sparse happy by restoring an even lock count on * this lock. In case we return here, we don't call into * __do_once_done but return early in the DO_ONCE() macro. */ __acquire(once_lock); |
46234253b net: move net_get... |
43 44 |
return false; } |
46234253b net: move net_get... |
45 46 |
return true; } |
c90aeb948 once: make helper... |
47 |
EXPORT_SYMBOL(__do_once_start); |
cf4c950b8 once: switch to n... |
48 |
void __do_once_done(bool *done, struct static_key_true *once_key, |
c90aeb948 once: make helper... |
49 50 51 52 53 54 55 56 |
unsigned long *flags) __releases(once_lock) { *done = true; spin_unlock_irqrestore(&once_lock, *flags); once_disable_jump(once_key); } EXPORT_SYMBOL(__do_once_done); |