From: Yu Ma yu.ma@intel.com
next inclusion category: performance bugzilla: https://gitee.com/src-openeuler/kernel/issues/IB1S01
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?...
--------------------------------
Skip 2-levels searching via find_next_zero_bit() when there is free slot in the word contains next_fd, as: (1) next_fd indicates the lower bound for the first free fd. (2) There is fast path inside of find_next_zero_bit() when size<=64 to speed up searching. (3) After fdt is expanded (the bitmap size doubled for each time of expansion), it would never be shrunk. The search size increases but there are few open fds available here.
This fast path is proposed by Mateusz Guzik mjguzik@gmail.com, and agreed by Jan Kara jack@suse.cz, which is more generic and scalable than previous versions. And on top of patch 1 and 2, it improves pts/blogbench-1.1.0 read by 8% and write by 4% on Intel ICX 160 cores configuration with v6.10-rc7.
Reviewed-by: Jan Kara jack@suse.cz Reviewed-by: Tim Chen tim.c.chen@linux.intel.com Signed-off-by: Yu Ma yu.ma@intel.com Link: https://lore.kernel.org/r/20240717145018.3972922-4-yu.ma@intel.com Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Jinjie Ruan ruanjinjie@huawei.com --- fs/file.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/fs/file.c b/fs/file.c index fdada5d563c3..8ccc7e01ffb3 100644 --- a/fs/file.c +++ b/fs/file.c @@ -482,6 +482,15 @@ static unsigned int find_next_fd(struct fdtable *fdt, unsigned int start) unsigned int maxfd = fdt->max_fds; /* always multiple of BITS_PER_LONG */ unsigned int maxbit = maxfd / BITS_PER_LONG; unsigned int bitbit = start / BITS_PER_LONG; + unsigned int bit; + + /* + * Try to avoid looking at the second level bitmap + */ + bit = find_next_zero_bit(&fdt->open_fds[bitbit], BITS_PER_LONG, + start & (BITS_PER_LONG - 1)); + if (bit < BITS_PER_LONG) + return bit + bitbit * BITS_PER_LONG;
bitbit = find_next_zero_bit(fdt->full_fds_bits, maxbit, bitbit) * BITS_PER_LONG; if (bitbit >= maxfd)