[PATCH v2] noinstr: Use asm_inline() in instrumentation_{begin,end}()
From: Josh Poimboeuf
Date: Mon Apr 14 2025 - 20:28:58 EST
Use asm_inline() in the instrumentation begin/end macros to prevent the
compiler from making poor inlining decisions based on the length of the
objtool annotations.
Without the objtool annotations, each macro resolves to a single NOP.
Using inline_asm() seems obviously correct here as it accurately
communicates the actual code size to the compiler.
These macros are used by WARN() and lockdep, so this change can affect a
lot of functions.
For a defconfig kernel built with GCC 14.2.1, bloat-o-meter reports a
0.17% increase in text size:
add/remove: 74/352 grow/shrink: 914/353 up/down: 80747/-47120 (33627)
Total: Before=19460272, After=19493899, chg +0.17%
The text growth is presumably due to increased inlining. A net total of
278 functions were removed (+74 / -352). Each of the removed functions
is likely inlined at multiple sites which explains the somewhat
significant code growth.
One example from Uros:
$ grep "<encode_string>" objdump.old
00000000004506e0 <encode_string>:
45113c: e8 9f f5 ff ff call 4506e0 <encode_string>
452bcb: e9 10 db ff ff jmp 4506e0 <encode_string>
453d33: e8 a8 c9 ff ff call 4506e0 <encode_string>
453ef7: e8 e4 c7 ff ff call 4506e0 <encode_string>
45549f: e8 3c b2 ff ff call 4506e0 <encode_string>
455843: e8 98 ae ff ff call 4506e0 <encode_string>
455b37: e8 a4 ab ff ff call 4506e0 <encode_string>
455b47: e8 94 ab ff ff call 4506e0 <encode_string>
4564fa: e8 e1 a1 ff ff call 4506e0 <encode_string>
456669: e8 72 a0 ff ff call 4506e0 <encode_string>
456691: e8 4a a0 ff ff call 4506e0 <encode_string>
4566a0: e8 3b a0 ff ff call 4506e0 <encode_string>
4569aa: e8 31 9d ff ff call 4506e0 <encode_string>
456e79: e9 62 98 ff ff jmp 4506e0 <encode_string>
456efe: e9 dd 97 ff ff jmp 4506e0 <encode_string>
All these are calls now inline:
encode_string 58 - -58
... where for example encode_putfh() grows by:
encode_putfh 70 118 +48
Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
---
v2:
- improve patch description
- extract from https://lore.kernel.org/cover.1744098446.git.jpoimboe@xxxxxxxxxx
include/linux/instrumentation.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/instrumentation.h b/include/linux/instrumentation.h
index bf675a8aef8a..b1007407d272 100644
--- a/include/linux/instrumentation.h
+++ b/include/linux/instrumentation.h
@@ -9,7 +9,7 @@
/* Begin/end of an instrumentation safe region */
#define __instrumentation_begin(c) ({ \
- asm volatile(__stringify(c) ": nop\n\t" \
+ asm_inline volatile(__stringify(c) ": nop\n\t" \
ANNOTATE_INSTR_BEGIN(__ASM_BREF(c)) \
: : "i" (c)); \
})
@@ -47,7 +47,7 @@
* part of the condition block and does not escape.
*/
#define __instrumentation_end(c) ({ \
- asm volatile(__stringify(c) ": nop\n\t" \
+ asm_inline volatile(__stringify(c) ": nop\n\t" \
ANNOTATE_INSTR_END(__ASM_BREF(c)) \
: : "i" (c)); \
})
--
2.49.0