• Linus Torvalds's avatar
    vfs: mostly undo glibc turning 'fstat()' into 'fstatat(AT_EMPTY_PATH)' · 9013c51c
    Linus Torvalds authored
    Mateusz reports that glibc turns 'fstat()' calls into 'fstatat()', and
    that seems to have been going on for quite a long time due to glibc
    having tried to simplify its stat logic into just one point.
    
    This turns out to cause completely unnecessary overhead, where we then
    go off and allocate the kernel side pathname, and actually look up the
    empty path.  Sure, our path lookup is quite optimized, but it still
    causes a fair bit of allocation overhead and a couple of completely
    unnecessary rounds of lockref accesses etc.
    
    This is all hopefully getting fixed in user space, and there is a patch
    floating around for just having glibc use the native fstat() system
    call.  But even with the current situation we can at least improve on
    things by catching the situation and short-circuiting it.
    
    Note that this is still measurably slower than just a plain 'fstat()',
    since just checking that the filename is actually empty is somewhat
    expensive due to inevitable user space access overhead from the kernel
    (ie verifying pointers, and SMAP on x86).  But it's still quite a bit
    faster than actually looking up the path for real.
    
    To quote numers from Mateusz:
     "Sapphire Rapids, will-it-scale, ops/s
    
      stock fstat	5088199
      patched fstat	7625244	(+49%)
      real fstat	8540383	(+67% / +12%)"
    
    where that 'stock fstat' is the glibc translation of fstat into
    fstatat() with an empty path, the 'patched fstat' is with this short
    circuiting of the path lookup, and the 'real fstat' is the actual native
    fstat() system call with none of this overhead.
    
    Link: https://lore.kernel.org/lkml/20230903204858.lv7i3kqvw6eamhgz@f/Reported-by: default avatarMateusz Guzik <mjguzik@gmail.com>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    9013c51c
stat.c 24.1 KB