fs: predict no error in close()
authorMateusz Guzik <mjguzik@gmail.com>
Sat, 1 Mar 2025 10:43:56 +0000 (11:43 +0100)
committerChristian Brauner <brauner@kernel.org>
Wed, 5 Mar 2025 17:25:36 +0000 (18:25 +0100)
Vast majority of the time the system call returns 0.

Letting the compiler know shortens the routine (119 -> 116) and the fast
path.

Disasm starting at the call to __fput_sync():

before:
<+55>:    call   0xffffffff816b0da0 <__fput_sync>
<+60>:    lea    0x201(%rbx),%eax
<+66>:    cmp    $0x1,%eax
<+69>:    jbe    0xffffffff816ab707 <__x64_sys_close+103>
<+71>:    mov    %ebx,%edx
<+73>:    movslq %ebx,%rax
<+76>:    and    $0xfffffffd,%edx
<+79>:    cmp    $0xfffffdfc,%edx
<+85>:    mov    $0xfffffffffffffffc,%rdx
<+92>:    cmove  %rdx,%rax
<+96>:    pop    %rbx
<+97>:    pop    %rbp
<+98>:    jmp    0xffffffff82242fa0 <__x86_return_thunk>
<+103>:   mov    $0xfffffffffffffffc,%rax
<+110>:   jmp    0xffffffff816ab700 <__x64_sys_close+96>
<+112>:   mov    $0xfffffffffffffff7,%rax
<+119>:   jmp    0xffffffff816ab700 <__x64_sys_close+96>

after:
<+56>:    call   0xffffffff816b0da0 <__fput_sync>
<+61>:    xor    %eax,%eax
<+63>:    test   %ebp,%ebp
<+65>:    jne    0xffffffff816ab6ea <__x64_sys_close+74>
<+67>:    pop    %rbx
<+68>:    pop    %rbp
<+69>:    jmp    0xffffffff82242fa0 <__x86_return_thunk> # the jmp out
<+74>:    lea    0x201(%rbp),%edx
<+80>:    mov    $0xfffffffffffffffc,%rax
<+87>:    cmp    $0x1,%edx
<+90>:    jbe    0xffffffff816ab6e3 <__x64_sys_close+67>
<+92>:    mov    %ebp,%edx
<+94>:    and    $0xfffffffd,%edx
<+97>:    cmp    $0xfffffdfc,%edx
<+103>:   cmovne %rbp,%rax
<+107>:   jmp    0xffffffff816ab6e3 <__x64_sys_close+67>
<+109>:   mov    $0xfffffffffffffff7,%rax
<+116>:   jmp    0xffffffff816ab6e3 <__x64_sys_close+67>

Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Link: https://lore.kernel.org/r/20250301104356.246031-1-mjguzik@gmail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/open.c

index 932e5a6..a8a5f84 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -1578,11 +1578,14 @@ SYSCALL_DEFINE1(close, unsigned int, fd)
         */
        __fput_sync(file);
 
+       if (likely(retval == 0))
+               return 0;
+
        /* can't restart close syscall because file table entry was cleared */
-       if (unlikely(retval == -ERESTARTSYS ||
-                    retval == -ERESTARTNOINTR ||
-                    retval == -ERESTARTNOHAND ||
-                    retval == -ERESTART_RESTARTBLOCK))
+       if (retval == -ERESTARTSYS ||
+           retval == -ERESTARTNOINTR ||
+           retval == -ERESTARTNOHAND ||
+           retval == -ERESTART_RESTARTBLOCK)
                retval = -EINTR;
 
        return retval;