fs/file.c: add fast path in find_next_fd()

JIRA: https://issues.redhat.com/browse/RHEL-38570
Upstream status: Linus

commit 0c40bf47cf2d9e1413b1e62826c89c2341e66e40
Author: Yu Ma <yu.ma@intel.com>
Date:   Wed Jul 17 10:50:18 2024 -0400

    fs/file.c: add fast path in find_next_fd()

    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: Ian Kent <ikent@redhat.com>
This commit is contained in:
Ian Kent 2025-06-06 10:39:28 +08:00
parent 0202a0e140
commit 773faedcd8
1 changed files with 9 additions and 0 deletions

View File

@ -457,6 +457,15 @@ static unsigned int find_next_fd(struct fdtable *fdt, unsigned int start)
unsigned int maxfd = fdt->max_fds;
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)