diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index 9fa735b4cb94..27c9ce32d9fc 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h @@ -247,10 +247,9 @@ extern bool arch_jump_label_transform_queue(struct jump_entry *entry, enum jump_label_type type); extern void arch_jump_label_transform_apply(void); extern int jump_label_text_reserved(void *start, void *end); -extern bool static_key_slow_inc(struct static_key *key); -extern bool static_key_fast_inc_not_disabled(struct static_key *key); +extern void static_key_slow_inc(struct static_key *key); extern void static_key_slow_dec(struct static_key *key); -extern bool static_key_slow_inc_cpuslocked(struct static_key *key); +extern void static_key_slow_inc_cpuslocked(struct static_key *key); extern void static_key_slow_dec_cpuslocked(struct static_key *key); extern int static_key_count(struct static_key *key); extern void static_key_enable(struct static_key *key); @@ -302,23 +301,11 @@ static __always_inline bool static_key_true(struct static_key *key) return false; } -static inline bool static_key_fast_inc_not_disabled(struct static_key *key) +static inline void static_key_slow_inc(struct static_key *key) { - int v; - STATIC_KEY_CHECK_USE(key); - /* - * Prevent key->enabled getting negative to follow the same semantics - * as for CONFIG_JUMP_LABEL=y, see kernel/jump_label.c comment. - */ - v = atomic_read(&key->enabled); - do { - if (v < 0 || (v + 1) < 0) - return false; - } while (!likely(atomic_try_cmpxchg(&key->enabled, &v, v + 1))); - return true; + atomic_inc(&key->enabled); } -#define static_key_slow_inc(key) static_key_fast_inc_not_disabled(key) static inline void static_key_slow_dec(struct static_key *key) { diff --git a/kernel/jump_label.c b/kernel/jump_label.c index d9c822bbffb8..4d6c6f5f60db 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c @@ -113,40 +113,9 @@ int static_key_count(struct static_key *key) } EXPORT_SYMBOL_GPL(static_key_count); -/* - * static_key_fast_inc_not_disabled - adds a user for a static key - * @key: static key that must be already enabled - * - * The caller must make sure that the static key can't get disabled while - * in this function. It doesn't patch jump labels, only adds a user to - * an already enabled static key. - * - * Returns true if the increment was done. Unlike refcount_t the ref counter - * is not saturated, but will fail to increment on overflow. - */ -bool static_key_fast_inc_not_disabled(struct static_key *key) +void static_key_slow_inc_cpuslocked(struct static_key *key) { - int v; - STATIC_KEY_CHECK_USE(key); - /* - * Negative key->enabled has a special meaning: it sends - * static_key_slow_inc() down the slow path, and it is non-zero - * so it counts as "enabled" in jump_label_update(). Note that - * atomic_inc_unless_negative() checks >= 0, so roll our own. - */ - v = atomic_read(&key->enabled); - do { - if (v <= 0 || (v + 1) < 0) - return false; - } while (!likely(atomic_try_cmpxchg(&key->enabled, &v, v + 1))); - - return true; -} -EXPORT_SYMBOL_GPL(static_key_fast_inc_not_disabled); - -bool static_key_slow_inc_cpuslocked(struct static_key *key) -{ lockdep_assert_cpus_held(); /* @@ -155,9 +124,15 @@ bool static_key_slow_inc_cpuslocked(struct static_key *key) * jump_label_update() process. At the same time, however, * the jump_label_update() call below wants to see * static_key_enabled(&key) for jumps to be updated properly. + * + * So give a special meaning to negative key->enabled: it sends + * static_key_slow_inc() down the slow path, and it is non-zero + * so it counts as "enabled" in jump_label_update(). Note that + * atomic_inc_unless_negative() checks >= 0, so roll our own. */ - if (static_key_fast_inc_not_disabled(key)) - return true; + for (int v = atomic_read(&key->enabled); v > 0; ) + if (likely(atomic_try_cmpxchg(&key->enabled, &v, v + 1))) + return; jump_label_lock(); if (atomic_read(&key->enabled) == 0) { @@ -169,23 +144,16 @@ bool static_key_slow_inc_cpuslocked(struct static_key *key) */ atomic_set_release(&key->enabled, 1); } else { - if (WARN_ON_ONCE(!static_key_fast_inc_not_disabled(key))) { - jump_label_unlock(); - return false; - } + atomic_inc(&key->enabled); } jump_label_unlock(); - return true; } -bool static_key_slow_inc(struct static_key *key) +void static_key_slow_inc(struct static_key *key) { - bool ret; - cpus_read_lock(); - ret = static_key_slow_inc_cpuslocked(key); + static_key_slow_inc_cpuslocked(key); cpus_read_unlock(); - return ret; } EXPORT_SYMBOL_GPL(static_key_slow_inc);