diff options
author | Denys Vlasenko <dvlasenk@redhat.com> | 2016-03-17 17:22:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-17 18:09:34 -0400 |
commit | a644fdf029f44f1ff76659154b411afeaeee1f43 (patch) | |
tree | 8527c0cc37154128dc7a8d7b3fd0a07fe13571f4 | |
parent | efc2cd7937fd3c32a8e0ffcdfa2603989f0a2faa (diff) |
include/asm-generic/atomic-long.h: force inlining of some atomic_long operations
Sometimes gcc mysteriously doesn't inline
very small functions we expect to be inlined. See
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66122
With this .config:
http://busybox.net/~vda/kernel_config_OPTIMIZE_INLINING_and_Os,
atomic_long_inc(), atomic_long_dec() and atomic_long_add()
functions get deinlined about 40 times. Examples of disassembly:
<atomic_long_inc> (21 copies, 147 calls):
55 push %rbp
48 89 e5 mov %rsp,%rbp
f0 48 ff 07 lock incq (%rdi)
5d pop %rbp
c3 retq
<atomic_long_dec> (4 copies, 14 calls) is similar to inc.
<atomic_long_add> (11 copies, 41 calls):
55 push %rbp
48 89 e5 mov %rsp,%rbp
f0 48 01 3e lock add %rdi,(%rsi)
5d pop %rbp
c3 retq
This patch fixes this via s/inline/__always_inline/.
Code size decrease after the patch is ~1.3k:
text data bss dec hex filename
92203657 20826112 36417536 149447305 8e86289 vmlinux
92202377 20826112 36417536 149446025 8e85d89 vmlinux4_atomiclong_after
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Thomas Graf <tgraf@suug.ch>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/asm-generic/atomic-long.h | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/include/asm-generic/atomic-long.h b/include/asm-generic/atomic-long.h index eb1973bad80b..5e1f345b58dd 100644 --- a/include/asm-generic/atomic-long.h +++ b/include/asm-generic/atomic-long.h | |||
@@ -98,14 +98,14 @@ ATOMIC_LONG_ADD_SUB_OP(sub, _release) | |||
98 | #define atomic_long_xchg(v, new) \ | 98 | #define atomic_long_xchg(v, new) \ |
99 | (ATOMIC_LONG_PFX(_xchg)((ATOMIC_LONG_PFX(_t) *)(v), (new))) | 99 | (ATOMIC_LONG_PFX(_xchg)((ATOMIC_LONG_PFX(_t) *)(v), (new))) |
100 | 100 | ||
101 | static inline void atomic_long_inc(atomic_long_t *l) | 101 | static __always_inline void atomic_long_inc(atomic_long_t *l) |
102 | { | 102 | { |
103 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; | 103 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
104 | 104 | ||
105 | ATOMIC_LONG_PFX(_inc)(v); | 105 | ATOMIC_LONG_PFX(_inc)(v); |
106 | } | 106 | } |
107 | 107 | ||
108 | static inline void atomic_long_dec(atomic_long_t *l) | 108 | static __always_inline void atomic_long_dec(atomic_long_t *l) |
109 | { | 109 | { |
110 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; | 110 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; |
111 | 111 | ||
@@ -113,7 +113,7 @@ static inline void atomic_long_dec(atomic_long_t *l) | |||
113 | } | 113 | } |
114 | 114 | ||
115 | #define ATOMIC_LONG_OP(op) \ | 115 | #define ATOMIC_LONG_OP(op) \ |
116 | static inline void \ | 116 | static __always_inline void \ |
117 | atomic_long_##op(long i, atomic_long_t *l) \ | 117 | atomic_long_##op(long i, atomic_long_t *l) \ |
118 | { \ | 118 | { \ |
119 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ | 119 | ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ |