diff options
author | Andi Kleen <ak@linux.intel.com> | 2017-03-19 21:02:22 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2017-03-20 16:08:44 +1100 |
commit | 451a546315b7928864574d2ed6c141d449b1ac1a (patch) | |
tree | b14be076bc431160911cd3359a66c15de2599b53 | |
parent | a6ce3d1c225589abbf47893a298224ddf29454f2 (diff) | |
download | linux-next-451a546315b7928864574d2ed6c141d449b1ac1a.tar.gz |
x86/atomic: move __arch_atomic_add_unless out of line
__arch_atomic_add_unless is fairly big and often used, so it's quite
expensive to inline it. But it's unlikely that a call makes much
difference for such a complex function doing an expensive atomic. So out
of line it.
This saves around 12k of text.
text data bss dec hex filename
9084246 5367600 11116544 25568390 1862486 vmlinux-atomic-add
9096494 5367568 11116544 25580606 186543e vmlinux-before-atomic-add
Link: http://lkml.kernel.org/r/20170315021431.13107-3-andi@firstfloor.org
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-rw-r--r-- | arch/x86/include/asm/atomic.h | 24 | ||||
-rw-r--r-- | arch/x86/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/lib/atomic.c | 27 |
3 files changed, 28 insertions, 24 deletions
diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h index 95dd167eb3af..5005444703f2 100644 --- a/arch/x86/include/asm/atomic.h +++ b/arch/x86/include/asm/atomic.h @@ -236,30 +236,6 @@ ATOMIC_OPS(xor, ^) #undef ATOMIC_OP /** - * __arch_atomic_add_unless - add unless the number is already a given value - * @v: pointer of type atomic_t - * @a: the amount to add to v... - * @u: ...unless v is equal to u. - * - * Atomically adds @a to @v, so long as @v was not already @u. - * Returns the old value of @v. - */ -static __always_inline int __arch_atomic_add_unless(atomic_t *v, int a, int u) -{ - int c, old; - c = arch_atomic_read(v); - for (;;) { - if (unlikely(c == (u))) - break; - old = arch_atomic_cmpxchg((v), c, c + (a)); - if (likely(old == c)) - break; - c = old; - } - return c; -} - -/** * arch_atomic_inc_short - increment of a short integer * @v: pointer to type int * diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index b98b8fdb7aaf..4063f072ee89 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -25,6 +25,7 @@ lib-y += memcpy_$(BITS).o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o +lib-y += atomic.o obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o diff --git a/arch/x86/lib/atomic.c b/arch/x86/lib/atomic.c new file mode 100644 index 000000000000..88c8372109f8 --- /dev/null +++ b/arch/x86/lib/atomic.c @@ -0,0 +1,27 @@ +#include <linux/module.h> +#include <asm/atomic.h> + +/** + * __arch_atomic_add_unless - add unless the number is already a given value + * @v: pointer of type atomic_t + * @a: the amount to add to v... + * @u: ...unless v is equal to u. + * + * Atomically adds @a to @v, so long as @v was not already @u. + * Returns the old value of @v. + */ +int __arch_atomic_add_unless(atomic_t *v, int a, int u) +{ + int c, old; + c = arch_atomic_read(v); + for (;;) { + if (unlikely(c == (u))) + break; + old = arch_atomic_cmpxchg((v), c, c + (a)); + if (likely(old == c)) + break; + c = old; + } + return c; +} +EXPORT_SYMBOL(__arch_atomic_add_unless); |