fs: move fd_install() slowpath into a dedicated routine and provide commentary
On stock kernel gcc 14 emits avoidable register spillage: endbr64 call ffffffff81374630 <__fentry__> push %r13 push %r12 push %rbx sub $0x8,%rsp [snip] Total fast path is 99 bytes. Moving the slowpath out avoids it and shortens the fast path to 74 bytes. Signed-off-by: Mateusz Guzik <mjguzik@gmail.com> Link: https://patch.msgid.link/20251110095634.1433061-1-mjguzik@gmail.com Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
21b561dab1
commit
9eda581bfe
35
fs/file.c
35
fs/file.c
|
|
@ -641,6 +641,34 @@ void put_unused_fd(unsigned int fd)
|
|||
|
||||
EXPORT_SYMBOL(put_unused_fd);
|
||||
|
||||
/*
|
||||
* Install a file pointer in the fd array while it is being resized.
|
||||
*
|
||||
* We need to make sure our update to the array does not get lost as the resizing
|
||||
* thread can be copying the content as we modify it.
|
||||
*
|
||||
* We have two ways to do it:
|
||||
* - go off CPU waiting for resize_in_progress to clear
|
||||
* - take the spin lock
|
||||
*
|
||||
* The latter is trivial to implement and saves us from having to might_sleep()
|
||||
* for debugging purposes.
|
||||
*
|
||||
* This is moved out of line from fd_install() to convince gcc to optimize that
|
||||
* routine better.
|
||||
*/
|
||||
static void noinline fd_install_slowpath(unsigned int fd, struct file *file)
|
||||
{
|
||||
struct files_struct *files = current->files;
|
||||
struct fdtable *fdt;
|
||||
|
||||
spin_lock(&files->file_lock);
|
||||
fdt = files_fdtable(files);
|
||||
VFS_BUG_ON(rcu_access_pointer(fdt->fd[fd]) != NULL);
|
||||
rcu_assign_pointer(fdt->fd[fd], file);
|
||||
spin_unlock(&files->file_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* fd_install - install a file pointer in the fd array
|
||||
* @fd: file descriptor to install the file in
|
||||
|
|
@ -658,14 +686,9 @@ void fd_install(unsigned int fd, struct file *file)
|
|||
return;
|
||||
|
||||
rcu_read_lock_sched();
|
||||
|
||||
if (unlikely(files->resize_in_progress)) {
|
||||
rcu_read_unlock_sched();
|
||||
spin_lock(&files->file_lock);
|
||||
fdt = files_fdtable(files);
|
||||
VFS_BUG_ON(rcu_access_pointer(fdt->fd[fd]) != NULL);
|
||||
rcu_assign_pointer(fdt->fd[fd], file);
|
||||
spin_unlock(&files->file_lock);
|
||||
fd_install_slowpath(fd, file);
|
||||
return;
|
||||
}
|
||||
/* coupled with smp_wmb() in expand_fdtable() */
|
||||
|
|
|
|||
Loading…
Reference in New Issue