]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/preempt: Optimize __preemp_count_add()/__preempt_count_sub()
authorHeiko Carstens <hca@linux.ibm.com>
Tue, 13 Jan 2026 19:43:58 +0000 (20:43 +0100)
committerHeiko Carstens <hca@linux.ibm.com>
Sat, 17 Jan 2026 14:52:49 +0000 (15:52 +0100)
Provide an inline assembly using alternatives to avoid the need of a
base register due to relocatable lowcore when adding or subtracting
small constants from preempt_count.

Main user is preempt_disable(), which subtracts one from
preempt_count. With this the generated code changes from

  10012c:       a7 b9 00 00             lghi    %r11,0
  100130:       eb 01 b3 a8 00 6a       asi     936(%r11),1

to something like this:

 10012c:        eb 01 03 a8 00 6a       asi     936,1

Kernel image size is reduced by 13kb (bloat-o-meter -t, defconfig, gcc15).

Reviewed-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/include/asm/preempt.h

index 6d6a28bee4e70abfc7d22d317dede7a8b12e1835..ef6ea3163c27e77a51b82f045a9afa7c4357cb1b 100644 (file)
@@ -84,7 +84,17 @@ static __always_inline void __preempt_count_add(int val)
         */
        if (!IS_ENABLED(CONFIG_PROFILE_ALL_BRANCHES)) {
                if (__builtin_constant_p(val) && (val >= -128) && (val <= 127)) {
-                       __atomic_add_const(val, &get_lowcore()->preempt_count);
+                       unsigned long lc_preempt;
+
+                       lc_preempt = offsetof(struct lowcore, preempt_count);
+                       asm_inline(
+                               ALTERNATIVE("asi        %[offzero](%%r0),%[val]\n",
+                                           "asi        %[offalt](%%r0),%[val]\n",
+                                           ALT_FEATURE(MFEATURE_LOWCORE))
+                               : "+m" (((struct lowcore *)0)->preempt_count)
+                               : [offzero] "i" (lc_preempt), [val] "i" (val),
+                                 [offalt] "i" (lc_preempt + LOWCORE_ALT_ADDRESS)
+                               : "cc");
                        return;
                }
        }