Re: [PATCH 01/26] mm: asi: Make some utility functions noinstr compatible

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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?




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux