]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
seqlock: annotate spinning as unlikely() in __read_seqcount_begin
authorMateusz Guzik <mjguzik@gmail.com>
Thu, 27 Jul 2023 18:03:55 +0000 (20:03 +0200)
committerChristian Brauner <brauner@kernel.org>
Sun, 22 Dec 2024 10:29:50 +0000 (11:29 +0100)
Annotation already used to be there, but got lost in 52ac39e5db5148f7
("seqlock: seqcount_t: Implement all read APIs as statement expressions").
Does not look like it was intentional.

Without it gcc 12 decides to compile the following in path_init:
        nd->m_seq = __read_seqcount_begin(&mount_lock.seqcount);
        nd->r_seq = __read_seqcount_begin(&rename_lock.seqcount);

into 2 cases of conditional jumps forward if the value is even, aka
branch prediction miss by default in the common case on x86-64.

With the patch jumps are only for odd values.

before:
[snip]
    mov    0x104fe96(%rip),%eax        # 0xffffffff82409680 <mount_lock>
    test   $0x1,%al
    je     0xffffffff813b97fa <path_init+122>
    pause
    mov    0x104fe8a(%rip),%eax        # 0xffffffff82409680 <mount_lock>
    test   $0x1,%al
    jne    0xffffffff813b97ee <path_init+110>
    mov    %eax,0x48(%rbx)
    mov    0x104fdfd(%rip),%eax        # 0xffffffff82409600 <rename_lock>
    test   $0x1,%al
    je     0xffffffff813b9813 <path_init+147>
    pause
    mov    0x104fdf1(%rip),%eax        # 0xffffffff82409600 <rename_lock>
    test   $0x1,%al
    jne    0xffffffff813b9807 <path_init+135>
[/snip]

after:
[snip]
   mov    0x104fec6(%rip),%eax        # 0xffffffff82409680 <mount_lock>
   test   $0x1,%al
   jne    0xffffffff813b99af <path_init+607>
   mov    %eax,0x48(%rbx)
   mov    0x104fe35(%rip),%eax        # 0xffffffff82409600 <rename_lock>
   test   $0x1,%al
   jne    0xffffffff813b999d <path_init+589>
[/snip]

Interestingly .text gets slightly smaller (as reported by size(1)):
before: 20702563
after: 20702429

Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Link: https://lore.kernel.org/r/20230727180355.813995-1-mjguzik@gmail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
include/linux/seqlock.h

index 5298765d6ca4827eb7bf8a9dca020f1383d3b901..eb20dcaa51b5902b33769aeb7a466798260f9373 100644 (file)
@@ -272,7 +272,7 @@ SEQCOUNT_LOCKNAME(mutex,        struct mutex,    true,     mutex)
 ({                                                                     \
        unsigned __seq;                                                 \
                                                                        \
-       while ((__seq = seqprop_sequence(s)) & 1)                       \
+       while (unlikely((__seq = seqprop_sequence(s)) & 1))             \
                cpu_relax();                                            \
                                                                        \
        kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX);                    \