diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-04 08:51:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-04 08:51:12 -0400 |
commit | d597690eef4142cf622fd469859ecc56506119b5 (patch) | |
tree | e0be5d05994de4b4243a4c76cf6ca13380c3eac3 /kernel/jump_label.c | |
parent | 96b585267f552d4b6a28ea8bd75e5ed03deb6e71 (diff) | |
parent | 9049fc745300c5e2236cbfc69f5e8cadb6f1f57c (diff) |
Merge branch 'akpm' (patches from Andrew)
Merge even more updates from Andrew Morton:
- dma-mapping API cleanup
- a few cleanups and misc things
- use jump labels in dynamic-debug
* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
dynamic_debug: add jump label support
jump_label: remove bug.h, atomic.h dependencies for HAVE_JUMP_LABEL
arm: jump label may reference text in __exit
tile: support static_key usage in non-module __exit sections
sparc: support static_key usage in non-module __exit sections
powerpc: add explicit #include <asm/asm-compat.h> for jump label
drivers/media/dvb-frontends/cxd2841er.c: avoid misleading gcc warning
MAINTAINERS: update email and list of Samsung HW driver maintainers
block: remove BLK_DEV_DAX config option
samples/kretprobe: fix the wrong type
samples/kretprobe: convert the printk to pr_info/pr_err
samples/jprobe: convert the printk to pr_info/pr_err
samples/kprobe: convert the printk to pr_info/pr_err
dma-mapping: use unsigned long for dma_attrs
media: mtk-vcodec: remove unused dma_attrs
include/linux/bitmap.h: cleanup
tree-wide: replace config_enabled() with IS_ENABLED()
drivers/fpga/Kconfig: fix build failure
Diffstat (limited to 'kernel/jump_label.c')
-rw-r--r-- | kernel/jump_label.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/kernel/jump_label.c b/kernel/jump_label.c index 0dbea887d625..f19aa02a8f48 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c @@ -14,6 +14,7 @@ #include <linux/err.h> #include <linux/static_key.h> #include <linux/jump_label_ratelimit.h> +#include <linux/bug.h> #ifdef HAVE_JUMP_LABEL @@ -56,6 +57,49 @@ jump_label_sort_entries(struct jump_entry *start, struct jump_entry *stop) static void jump_label_update(struct static_key *key); +/* + * There are similar definitions for the !HAVE_JUMP_LABEL case in jump_label.h. + * The use of 'atomic_read()' requires atomic.h and its problematic for some + * kernel headers such as kernel.h and others. Since static_key_count() is not + * used in the branch statements as it is for the !HAVE_JUMP_LABEL case its ok + * to have it be a function here. Similarly, for 'static_key_enable()' and + * 'static_key_disable()', which require bug.h. This should allow jump_label.h + * to be included from most/all places for HAVE_JUMP_LABEL. + */ +int static_key_count(struct static_key *key) +{ + /* + * -1 means the first static_key_slow_inc() is in progress. + * static_key_enabled() must return true, so return 1 here. + */ + int n = atomic_read(&key->enabled); + + return n >= 0 ? n : 1; +} +EXPORT_SYMBOL_GPL(static_key_count); + +void static_key_enable(struct static_key *key) +{ + int count = static_key_count(key); + + WARN_ON_ONCE(count < 0 || count > 1); + + if (!count) + static_key_slow_inc(key); +} +EXPORT_SYMBOL_GPL(static_key_enable); + +void static_key_disable(struct static_key *key) +{ + int count = static_key_count(key); + + WARN_ON_ONCE(count < 0 || count > 1); + + if (count) + static_key_slow_dec(key); +} +EXPORT_SYMBOL_GPL(static_key_disable); + void static_key_slow_inc(struct static_key *key) { int v, v1; @@ -235,6 +279,15 @@ void __init jump_label_init(void) struct static_key *key = NULL; struct jump_entry *iter; + /* + * Since we are initializing the static_key.enabled field with + * with the 'raw' int values (to avoid pulling in atomic.h) in + * jump_label.h, let's make sure that is safe. There are only two + * cases to check since we initialize to 0 or 1. + */ + BUILD_BUG_ON((int)ATOMIC_INIT(0) != 0); + BUILD_BUG_ON((int)ATOMIC_INIT(1) != 1); + jump_label_lock(); jump_label_sort_entries(iter_start, iter_stop); |