alloc_fd() has a sanity check inside to make sure the FILE object mapping to the allocated fd is NULL. Move the sanity check from performance critical alloc_fd() path to non performance critical put_unused_fd() path. As the initial NULL FILE object condition can be assured by zero initialization in init_file, we just need to make sure that it is NULL when recycling fd back. There are 3 functions call __put_unused_fd() to return fd, file_close_fd_locked(), do_close_on_exec() and put_unused_fd(). For file_close_fd_locked() and do_close_on_exec(), they have implemented NULL check already. Adds NULL check to put_unused_fd() to cover all release paths. Combined with patch 1 and 2 in series, pts/blogbench-1.1.0 read improved by 32%, write improved by 15% on Intel ICX 160 cores configuration with v6.8-rc6. Reviewed-by: Tim Chen <tim.c.chen@xxxxxxxxxxxxxxx> Signed-off-by: Yu Ma <yu.ma@xxxxxxxxx> --- fs/file.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/fs/file.c b/fs/file.c index a0e94a178c0b..59d62909e2e3 100644 --- a/fs/file.c +++ b/fs/file.c @@ -548,13 +548,6 @@ static int alloc_fd(unsigned start, unsigned end, unsigned flags) else __clear_close_on_exec(fd, fdt); error = fd; -#if 1 - /* Sanity check */ - if (rcu_access_pointer(fdt->fd[fd]) != NULL) { - printk(KERN_WARNING "alloc_fd: slot %d not NULL!\n", fd); - rcu_assign_pointer(fdt->fd[fd], NULL); - } -#endif out: spin_unlock(&files->file_lock); @@ -572,7 +565,7 @@ int get_unused_fd_flags(unsigned flags) } EXPORT_SYMBOL(get_unused_fd_flags); -static void __put_unused_fd(struct files_struct *files, unsigned int fd) +static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) { struct fdtable *fdt = files_fdtable(files); __clear_open_fd(fd, fdt); @@ -583,7 +576,12 @@ static void __put_unused_fd(struct files_struct *files, unsigned int fd) void put_unused_fd(unsigned int fd) { struct files_struct *files = current->files; + struct fdtable *fdt = files_fdtable(files); spin_lock(&files->file_lock); + if (unlikely(rcu_access_pointer(fdt->fd[fd]))) { + printk(KERN_WARNING "put_unused_fd: slot %d not NULL!\n", fd); + rcu_assign_pointer(fdt->fd[fd], NULL); + } __put_unused_fd(files, fd); spin_unlock(&files->file_lock); } -- 2.43.0