Le 22/01/2026 à 12:07, Thomas Weißschuh a écrit :
On Thu, Jan 22, 2026 at 11:58:04AM +0100, Christophe Leroy (CS GROUP) wrote:


Le 22/01/2026 à 11:49, Thomas Weißschuh a écrit :
On Thu, Jan 22, 2026 at 11:27:43AM +0100, Christophe Leroy (CS GROUP) wrote:
Hi Thomas,

Le 22/01/2026 à 10:50, Thomas Weißschuh a écrit :
Hi Alexander,

On Thu, Jan 22, 2026 at 09:39:09AM +0000, Sverdlin, Alexander wrote:
Hi Thomas, Christophe,

On Wed, 2026-01-14 at 08:26 +0100, Thomas Weißschuh wrote:
For consistency with __vdso_clock_gettime64() there should also be a
64-bit variant of clock_getres(). This will allow the extension of
CONFIG_COMPAT_32BIT_TIME to the vDSO and finally the removal of 32-bit
time types from the kernel and UAPI.

Signed-off-by: Thomas Weißschuh <[email protected]>

I've bisected this patch to cause the following build failure on my side:

     LDS     arch/powerpc/kernel/vdso/vdso32.lds
     VDSO32A arch/powerpc/kernel/vdso/sigtramp32-32.o
     VDSO32A arch/powerpc/kernel/vdso/gettimeofday-32.o
     VDSO32A arch/powerpc/kernel/vdso/datapage-32.o
     VDSO32A arch/powerpc/kernel/vdso/cacheflush-32.o
     VDSO32A arch/powerpc/kernel/vdso/note-32.o
     VDSO32A arch/powerpc/kernel/vdso/getcpu-32.o
     VDSO32A arch/powerpc/kernel/vdso/getrandom-32.o
     VDSO32A arch/powerpc/kernel/vdso/vgetrandom-chacha-32.o
     VDSO32C arch/powerpc/kernel/vdso/vgettimeofday-32.o
     VDSO32C arch/powerpc/kernel/vdso/vgetrandom-32.o
     VDSO32A arch/powerpc/kernel/vdso/crtsavres-32.o
     VDSO32L arch/powerpc/kernel/vdso/vdso32.so.dbg
arch/powerpc/kernel/vdso/vdso32.so.dbg: dynamic relocations are not supported
make[2]: *** [arch/powerpc/kernel/vdso/Makefile:79: 
arch/powerpc/kernel/vdso/vdso32.so.dbg] Error 1
make[1]: *** [arch/powerpc/Makefile:388: vdso_prepare] Error 2

Thanks for the report!

Does it ring any bells? What could I try/test?

Not immediately, but I'll look into it.

I'm using gcc-15.2.0 and binutils 2.45.1.

Is this a toolchain from 
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdn.kernel.org%2Fpub%2Ftools%2Fcrosstool%2F&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C7f1accdfc7ef4d8ea82c08de59a664b8%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639046768343248286%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=7WB%2FCB2ZDhP9bD0GYwEftyRwfDCoRwuQ5uMA98JhfmE%3D&reserved=0
 ?
Could you also share your configuration?

I've just been able to reproduce it with ppc64_defconfig +
CONFIG_CC_OPTIMIZE_FOR_SIZE

Thanks for the hint, no I can reproduce it, too.

    VDSO32L arch/powerpc/kernel/vdso/vdso32.so.dbg
arch/powerpc/kernel/vdso/vdso32.so.dbg: dynamic relocations are not
supported
make[2]: *** [arch/powerpc/kernel/vdso/Makefile:79:
arch/powerpc/kernel/vdso/vdso32.so.dbg] Error 1
make[1]: *** [arch/powerpc/Makefile:388: vdso_prepare] Error 2
make: *** [Makefile:248: __sub-make] Error 2

I'll investigate

It seems the compiler decides to call memset(), which is not valid from the
vDSO. We are are using -ffreestanding. Disabling CONFIG_INIT_STACK_ALL_ZERO
fixes the issue. So I guess we should a) figure out why -ffreestanding does
not seem to work here and b) exclude the vDSO from the stack initialization
logic.


Ah, ok.

Reminds me commit b91c8c42ffdd ("lib/vdso: Force inlining of
__cvdso_clock_gettime_common()")

Good pointer.

Problem fixed with:

diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 95df0153f05ab..4399e143d43a5 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -421,7 +421,7 @@ static __maybe_unused __kernel_old_time_t
__cvdso_time(__kernel_old_time_t *time
  #endif /* VDSO_HAS_TIME */

  #ifdef VDSO_HAS_CLOCK_GETRES
-static __maybe_unused
+static __always_inline
  bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t
clock,
                                 struct __kernel_timespec *res)
  {

Do you want to run the measurements for this one, too and submit a fix?
This should get us past the immediate breakage.

I'm travelling at the moment and won't be able to come with measurement before next month. But the performance degradation is obvious.

With the fix, the function is stackless:

00000728 <__c_kernel_clock_getres>:
 728:   28 03 00 17     cmplwi  r3,23
 72c:   41 81 00 50     bgt     77c <__c_kernel_clock_getres+0x54>
 730:   81 45 00 04     lwz     r10,4(r5)
 734:   6d 49 80 00     xoris   r9,r10,32768
 738:   2c 09 ff ff     cmpwi   r9,-1
 73c:   40 82 00 08     bne     744 <__c_kernel_clock_getres+0x1c>
 740:   3c a5 00 01     addis   r5,r5,1
 744:   39 20 00 01     li      r9,1
 748:   7d 29 18 30     slw     r9,r9,r3
 74c:   71 2a 08 93     andi.   r10,r9,2195
 750:   41 82 00 18     beq     768 <__c_kernel_clock_getres+0x40>
 754:   81 25 08 c8     lwz     r9,2248(r5)
 758:   2c 04 00 00     cmpwi   r4,0
 75c:   40 82 00 40     bne     79c <__c_kernel_clock_getres+0x74>
 760:   38 60 00 00     li      r3,0
 764:   4e 80 00 20     blr
 768:   71 2a 00 60     andi.   r10,r9,96
 76c:   40 82 00 24     bne     790 <__c_kernel_clock_getres+0x68>
 770:   75 29 00 ff     andis.  r9,r9,255
 774:   39 20 00 01     li      r9,1
 778:   40 82 ff e0     bne     758 <__c_kernel_clock_getres+0x30>
 77c:   38 00 00 f7     li      r0,247
 780:   44 00 00 02     sc
 784:   40 e3 00 08     bns+    78c <__c_kernel_clock_getres+0x64>
 788:   7c 63 00 d0     neg     r3,r3
 78c:   4e 80 00 20     blr
 790:   3d 20 00 0f     lis     r9,15
 794:   61 29 42 40     ori     r9,r9,16960
 798:   4b ff ff c0     b       758 <__c_kernel_clock_getres+0x30>
 79c:   39 40 00 00     li      r10,0
 7a0:   91 24 00 04     stw     r9,4(r4)
 7a4:   91 44 00 00     stw     r10,0(r4)
 7a8:   4b ff ff b8     b       760 <__c_kernel_clock_getres+0x38>

Without the fix, see below, __c_kernel_clock_getres() has to setup a stack in order to call __cvdso_clock_getres_common(), and in addition we see that __cvdso_clock_getres_common() is more or less the same size as __c_kernel_clock_getres() above, so time increase unquestionable.

00000000 <__cvdso_clock_getres_common>:
   0:   28 04 00 17     cmplwi  r4,23
   4:   41 81 00 8c     bgt     90 <__cvdso_clock_getres_common+0x90>
   8:   81 43 00 04     lwz     r10,4(r3)
   c:   6d 49 80 00     xoris   r9,r10,32768
  10:   2c 09 ff ff     cmpwi   r9,-1
  14:   40 82 00 08     bne     1c <__cvdso_clock_getres_common+0x1c>
  18:   3c 63 00 01     addis   r3,r3,1
  1c:   39 20 00 01     li      r9,1
  20:   7d 24 20 30     slw     r4,r9,r4
  24:   70 89 08 93     andi.   r9,r4,2195
  28:   41 82 00 34     beq     5c <__cvdso_clock_getres_common+0x5c>
  2c:   81 23 08 c8     lwz     r9,2248(r3)
  30:   39 40 00 00     li      r10,0
  34:   2c 05 00 00     cmpwi   r5,0
  38:   41 82 00 1c     beq     54 <__cvdso_clock_getres_common+0x54>
  3c:   38 c0 00 00     li      r6,0
  40:   38 e0 00 00     li      r7,0
  44:   91 45 00 08     stw     r10,8(r5)
  48:   91 25 00 0c     stw     r9,12(r5)
  4c:   90 c5 00 00     stw     r6,0(r5)
  50:   90 e5 00 04     stw     r7,4(r5)
  54:   38 60 00 01     li      r3,1
  58:   48 00 00 20     b       78 <__cvdso_clock_getres_common+0x78>
  5c:   70 89 00 60     andi.   r9,r4,96
  60:   40 82 00 20     bne     80 <__cvdso_clock_getres_common+0x80>
  64:   74 84 00 ff     andis.  r4,r4,255
  68:   38 60 00 00     li      r3,0
  6c:   39 40 00 00     li      r10,0
  70:   39 20 00 01     li      r9,1
  74:   40 82 ff c0     bne     34 <__cvdso_clock_getres_common+0x34>
  78:   54 63 07 fe     clrlwi  r3,r3,31
  7c:   4e 80 00 20     blr
  80:   3d 20 00 0f     lis     r9,15
  84:   39 40 00 00     li      r10,0
  88:   61 29 42 40     ori     r9,r9,16960
  8c:   4b ff ff a8     b       34 <__cvdso_clock_getres_common+0x34>
  90:   38 60 00 00     li      r3,0
  94:   4b ff ff e4     b       78 <__cvdso_clock_getres_common+0x78>

000007c0 <__c_kernel_clock_getres>:
 7c0:   94 21 ff d0     stwu    r1,-48(r1)
 7c4:   7c 08 02 a6     mflr    r0
 7c8:   bf a1 00 24     stmw    r29,36(r1)
 7cc:   7c 7e 1b 78     mr      r30,r3
 7d0:   7c bd 2b 78     mr      r29,r5
 7d4:   7c 9f 23 78     mr      r31,r4
 7d8:   38 a0 00 10     li      r5,16
 7dc:   90 01 00 34     stw     r0,52(r1)
 7e0:   38 80 00 00     li      r4,0
 7e4:   38 61 00 08     addi    r3,r1,8
 7e8:   48 00 00 01     bl      7e8 <__c_kernel_clock_getres+0x28>
                        7e8: R_PPC_REL24        memset
 7ec:   7f c4 f3 78     mr      r4,r30
 7f0:   7f a3 eb 78     mr      r3,r29
 7f4:   38 a1 00 08     addi    r5,r1,8
 7f8:   4b ff f8 09     bl      0 <__cvdso_clock_getres_common>
 7fc:   2c 03 00 00     cmpwi   r3,0
 800:   40 82 00 24     bne     824 <__c_kernel_clock_getres+0x64>
 804:   38 00 00 f7     li      r0,247
 808:   7f c3 f3 78     mr      r3,r30
 80c:   7f e4 fb 78     mr      r4,r31
 810:   44 00 00 02     sc
 814:   40 e3 00 08     bns+    81c <__c_kernel_clock_getres+0x5c>
 818:   7c 63 00 d0     neg     r3,r3
 81c:   39 61 00 30     addi    r11,r1,48
 820:   48 00 00 00     b       820 <__c_kernel_clock_getres+0x60>
                        820: R_PPC_REL24        _restgpr_29_x
 824:   2c 1f 00 00     cmpwi   r31,0
 828:   41 82 00 14     beq     83c <__c_kernel_clock_getres+0x7c>
 82c:   81 21 00 0c     lwz     r9,12(r1)
 830:   91 3f 00 00     stw     r9,0(r31)
 834:   81 21 00 14     lwz     r9,20(r1)
 838:   91 3f 00 04     stw     r9,4(r31)
 83c:   38 60 00 00     li      r3,0
 840:   4b ff ff dc     b       81c <__c_kernel_clock_getres+0x5c>


I'll still try to get the stack initialization out of the vDSO.
It might bite us at any time in the future. As these options are meant
to prevent information leaks and the vDSO has no sensitive information in
the first place, we might as well filter them out.

Well, from the first day we converted powerpc to C time vdso, we've done our best in order to keep vdso stackless. So I'm not sure it is worth dealing with the above. Indeed if keeping it as is helps us detect everytime a change jeoperdises the stackless approach, that's not bad.

Christophe

Reply via email to