On Fri, 1 Nov 2024 at 21:27, Thomas Gleixner <tglx@xxxxxxxxxxxxx> wrote: > On Thu, Oct 31 2024 at 18:44, Junaid Shahid wrote: > What actually works by some definition of "works" is: > > static __always_inline void __foo(void) { } > > static inline void foo(void) > { > __(foo); > } > > static inline noinstr void foo_noinstr(void) > { > __(foo); > } > > The problem is that both GCC and clang optimize foo[_noinstr]() away and > then follow the __always_inline directive of __foo() even if I make > __foo() insanely large and have a gazillion of different functions > marked noinline invoking foo() or foo_noinstr(), unless I add -fno-inline > to the command line. In this experiment did you modify the definition of noinstr to remove noinline? Otherwise I always get out-of-line calls (as you'd expect from the noinline). > Which means it's not much different from just having '__always_inline > foo()' without the wrappers.... > > Compilers clearly lack a --do-what-I-mean command line option. > > Now if I'm truly nasty then both compilers do what I mean even without a > magic command line option: > > static __always_inline void __foo(void) { } > > static __maybe_unused void foo(void) > { > __(foo); > } > > static __maybe_unused noinstr void foo_noinstr(void) > { > __(foo); > } I don't see any difference with __maybe_unused: if the noinline is there it's never inlined, otherwise with the wrapper technique it's always inlined regardless of __maybe_unused: static __always_inline void __big(void) { asm volatile( "nop; nop; nop; nop; nop; nop; nop; nop; nop;" // and so on "nop; nop; nop; nop; nop; nop; nop; nop; nop;" ); } static inline __section(".noinstr.text") void big_noinstr(void) { __big(); } When I call big_noinstr() from a noinstr function I see: Dump of assembler code for function asi_exit: 0xffffffff811e0080 <+0>: endbr64 0xffffffff811e0084 <+4>: nop 0xffffffff811e0085 <+5>: nop ...and so on I'm using GCC 14.2.0. (I thought maybe this was because I used asm volatile nops to embiggen the function but I see the same thing with a big stream of volatile C statements). I think we might have no choice but to always use __always_inline/noinline for code that's called from both sections - seems there's no way to tell the compiler "I don't care if you inline it, but it we can't cross a section boundary". Am I missing anything?