mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Ma, Yu" <yu.ma@intel.com>
To: Jan Kara <jack@suse.cz>
Cc: viro@zeniv.linux.org.uk, brauner@kernel.org, mjguzik@gmail.com,
	edumazet@google.com, linux-fsdevel@vger.kernel.org,
	linux-kernel@vger.kernel.org, pan.deng@intel.com,
	tianyou.li@intel.com, tim.c.chen@intel.com,
	tim.c.chen@linux.intel.com, yu.ma@intel.com
Subject: Re: [PATCH v2 1/3] fs/file.c: add fast path in alloc_fd()
Date: Tue, 25 Jun 2024 23:33:34 +0800	[thread overview]
Message-ID: <87a1279c-c5df-4f3b-936d-c9b8ed58f46e@intel.com> (raw)
In-Reply-To: <20240625125309.y2gs4j5jr35kc4z5@quack3>


On 6/25/2024 8:53 PM, Jan Kara wrote:
> On Tue 25-06-24 13:52:57, Jan Kara wrote:
>> On Sat 22-06-24 11:49:02, Yu Ma wrote:
>>> There is available fd in the lower 64 bits of open_fds bitmap for most cases
>>> when we look for an available fd slot. Skip 2-levels searching via
>>> find_next_zero_bit() for this common fast path.
>>>
>>> Look directly for an open bit in the lower 64 bits of open_fds bitmap when a
>>> free slot is available there, as:
>>> (1) The fd allocation algorithm would always allocate fd from small to large.
>>> Lower bits in open_fds bitmap would be used much more frequently than higher
>>> bits.
>>> (2) 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.
>>> (3) find_next_zero_bit() itself has a fast path inside to speed up searching
>>> when size<=64.
>>>
>>> Besides, "!start" is added to fast path condition to ensure the allocated fd is
>>> greater than start (i.e. >=0), given alloc_fd() is only called in two scenarios:
>>> (1) Allocating a new fd (the most common usage scenario) via
>>> get_unused_fd_flags() to find fd start from bit 0 in fdt (i.e. start==0).
>>> (2) Duplicating a fd (less common usage) via dup_fd() to find a fd start from
>>> old_fd's index in fdt, which is only called by syscall fcntl.
>>>
>>> With the fast path added in alloc_fd(), pts/blogbench-1.1.0 read is improved
>>> by 17% and write by 9% on Intel ICX 160 cores configuration with v6.10-rc4.
>>>
>>> Reviewed-by: Tim Chen <tim.c.chen@linux.intel.com>
>>> Signed-off-by: Yu Ma <yu.ma@intel.com>
>>> ---
>>>   fs/file.c | 35 +++++++++++++++++++++--------------
>>>   1 file changed, 21 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/fs/file.c b/fs/file.c
>>> index a3b72aa64f11..50e900a47107 100644
>>> --- a/fs/file.c
>>> +++ b/fs/file.c
>>> @@ -515,28 +515,35 @@ static int alloc_fd(unsigned start, unsigned end, unsigned flags)
>>>   	if (fd < files->next_fd)
>>>   		fd = files->next_fd;
>>>   
>>> -	if (fd < fdt->max_fds)
>>> +	error = -EMFILE;
>>> +	if (likely(fd < fdt->max_fds)) {
>>> +		if (~fdt->open_fds[0] && !start) {
>>> +			fd = find_next_zero_bit(fdt->open_fds, BITS_PER_LONG, fd);
>> So I don't think this is quite correct. If files->next_fd is set, we could
>> end up calling find_next_zero_bit() starting from quite high offset causing
>> a regression? Also because we don't expand in this case, we could cause access
>> beyond end of fdtable?
> OK, I've misunderstood the next_fd logic. next_fd is the lowest 0-bit in
> the open_fds bitmap so if next_fd is big, the ~fdt->open_fds[0] should
> be false. As such the above condition could be rewritten as:
>
> 		if (!start && files->next_fd < BITS_PER_LONG)
>
> to avoid loading the first bitmap long if we know it is full? Or we could
> maybe go as far as:
>
> 		if (!start && fd < BITS_PER_LONG && !test_bit(fd, fdt->open_fds))
> 			goto fastreturn;
>
> because AFAIU this should work in exactly the same cases as your code?
>
> 								Honza

Thanks Honza for the good concern and suggestions here, while both above 
conditions are not enough to ensure that there is available fd in the 
first 64 bits of open_fds. As next_fd just means there is no available 
fd before next_fd, just imagine that fd from 0 to 66 are already 
occupied, now fd=3 is returned back, then next_fd would be set as 3 per 
fd recycling logic (i.e. in __put_unused_fd()), next time when 
alloc_fd() being called, it would return fd=3 to the caller and set 
next_fd=4. Then next time when alloc_fd() being called again, 
next_fd==4, but actually it's already been occupied. So 
find_next_zero_bit() is needed to find the real 0 bit anyway. The 
conditions should either be like it is in patch or if (!start && 
!test_bit(0, fdt->full_fds_bits)), the latter should also have the 
bitmap loading cost, but another point is that a bit in full_fds_bits 
represents 64 bits in open_fds, no matter fd >64 or not, full_fds_bits 
should be loaded any way, maybe we can modify the condition to use 
full_fds_bits ?

>>> +			goto fastreturn;
>>> +		}
>>>   		fd = find_next_fd(fdt, fd);
>>> +	}
>>> +
>>> +	if (unlikely(fd >= fdt->max_fds)) {
>>> +		error = expand_files(files, fd);
>>> +		if (error < 0)
>>> +			goto out;
>>> +		/*
>>> +		 * If we needed to expand the fs array we
>>> +		 * might have blocked - try again.
>>> +		 */
>>> +		if (error)
>>> +			goto repeat;
>>> +	}
>>>   
>>> +fastreturn:
>>>   	/*
>>>   	 * N.B. For clone tasks sharing a files structure, this test
>>>   	 * will limit the total number of files that can be opened.
>>>   	 */
>>> -	error = -EMFILE;
>>> -	if (fd >= end)
>>> +	if (unlikely(fd >= end))
>>>   		goto out;
>>>   
>>> -	error = expand_files(files, fd);
>>> -	if (error < 0)
>>> -		goto out;
>>> -
>>> -	/*
>>> -	 * If we needed to expand the fs array we
>>> -	 * might have blocked - try again.
>>> -	 */
>>> -	if (error)
>>> -		goto repeat;
>>> -
>>>   	if (start <= files->next_fd)
>>>   		files->next_fd = fd + 1;
>>>   
>>> -- 
>>> 2.43.0
>>>
>> -- 
>> Jan Kara <jack@suse.com>
>> SUSE Labs, CR
>>

  reply	other threads:[~2024-06-25 15:33 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-14 16:34 [PATCH 0/3] fs/file.c: optimize the critical section of Yu Ma
2024-06-14 16:34 ` [PATCH 1/3] fs/file.c: add fast path in alloc_fd() Yu Ma
2024-06-15  6:31   ` Mateusz Guzik
2024-06-16  4:01     ` Ma, Yu
2024-06-17 17:49     ` Tim Chen
2024-06-19 10:36   ` David Laight
2024-06-19 17:09     ` Ma, Yu
2024-06-14 16:34 ` [PATCH 2/3] fs/file.c: conditionally clear full_fds Yu Ma
2024-06-14 16:34 ` [PATCH 3/3] fs/file.c: move sanity_check from alloc_fd() to put_unused_fd() Yu Ma
2024-06-15  4:41   ` Mateusz Guzik
2024-06-15  5:07     ` Mateusz Guzik
2024-06-17 17:55       ` Tim Chen
2024-06-17 17:59         ` Mateusz Guzik
2024-06-17 18:04         ` Tim Chen
2024-06-18  8:35           ` Michal Hocko
2024-06-18  9:06             ` Mateusz Guzik
2024-06-18 20:40             ` Tim Chen
2024-06-16  3:47     ` Ma, Yu
2024-06-17 11:23       ` Mateusz Guzik
2024-06-17 17:22         ` Ma, Yu
2024-06-17  8:36     ` Christian Brauner
2024-06-22 15:49 ` [PATCH v2 0/3] fs/file.c: optimize the critical section of file_lock in Yu Ma
2024-06-22 15:49   ` [PATCH v2 1/3] fs/file.c: add fast path in alloc_fd() Yu Ma
2024-06-25 11:52     ` Jan Kara
2024-06-25 12:53       ` Jan Kara
2024-06-25 15:33         ` Ma, Yu [this message]
2024-06-26 11:54           ` Jan Kara
2024-06-26 16:43             ` Tim Chen
2024-06-26 16:52               ` Tim Chen
2024-06-27 12:09                 ` Jan Kara
2024-06-27 12:20                   ` Mateusz Guzik
2024-06-27 16:21                   ` Tim Chen
2024-06-26 19:13             ` Mateusz Guzik
2024-06-27 14:03               ` Jan Kara
2024-06-27 15:33               ` Christian Brauner
2024-06-27 18:27                 ` Ma, Yu
2024-06-27 19:59                   ` Mateusz Guzik
2024-06-28  9:12                     ` Jan Kara
2024-06-29 15:41                       ` Ma, Yu
2024-06-29 15:46                         ` Mateusz Guzik
2024-06-29 14:23                     ` Ma, Yu
2024-06-22 15:49   ` [PATCH v2 2/3] fs/file.c: conditionally clear full_fds Yu Ma
2024-06-25 11:54     ` Jan Kara
2024-06-25 15:41       ` Ma, Yu
2024-06-22 15:49   ` [PATCH v2 3/3] fs/file.c: remove sanity_check from alloc_fd() Yu Ma
2024-06-25 12:08     ` Jan Kara
2024-06-25 13:09       ` Mateusz Guzik
2024-06-25 13:11         ` Mateusz Guzik
2024-06-25 13:30           ` Jan Kara
2024-06-26 13:10             ` Christian Brauner
2024-07-03 14:33 ` [PATCH v3 0/3] fs/file.c: optimize the critical section of file_lock in Yu Ma
2024-07-03 14:33   ` [PATCH v3 1/3] fs/file.c: remove sanity_check and add likely/unlikely in alloc_fd() Yu Ma
2024-07-03 14:34     ` Christian Brauner
2024-07-03 14:46       ` Ma, Yu
2024-07-04 10:11       ` Jan Kara
2024-07-04 14:45         ` Ma, Yu
2024-07-04 15:41           ` Jan Kara
2024-07-03 14:33   ` [PATCH v3 2/3] fs/file.c: conditionally clear full_fds Yu Ma
2024-07-03 14:33   ` [PATCH v3 3/3] fs/file.c: add fast path in find_next_fd() Yu Ma
2024-07-03 14:17     ` Mateusz Guzik
2024-07-03 14:28       ` Ma, Yu
2024-07-04 10:07       ` Jan Kara
2024-07-04 10:03     ` Jan Kara
2024-07-04 14:50       ` Ma, Yu
2024-07-04 17:44     ` Mateusz Guzik
2024-07-04 21:55       ` Jan Kara
2024-07-05  7:56         ` Ma, Yu
2024-07-09  8:32           ` Ma, Yu
2024-07-09 10:17             ` Mateusz Guzik
2024-07-10 23:40               ` Tim Chen
2024-07-11  9:27                 ` Ma, Yu
2024-07-13  2:39 ` [PATCH v4 0/3] fs/file.c: optimize the critical section of file_lock in Yu Ma
2024-07-13  2:39   ` [PATCH v4 1/3] fs/file.c: remove sanity_check and add likely/unlikely in alloc_fd() Yu Ma
2024-07-16 11:11     ` Jan Kara
2024-07-13  2:39   ` [PATCH v4 2/3] fs/file.c: conditionally clear full_fds Yu Ma
2024-07-13  2:39   ` [PATCH v4 3/3] fs/file.c: add fast path in find_next_fd() Yu Ma
2024-07-16 11:19     ` Jan Kara
2024-07-16 12:37       ` Ma, Yu
2024-07-17 14:50 ` [PATCH v5 0/3] fs/file.c: optimize the critical section of file_lock in Yu Ma
2024-07-17 14:50   ` [PATCH v5 1/3] fs/file.c: remove sanity_check and add likely/unlikely in alloc_fd() Yu Ma
2024-08-06 13:44     ` kernel test robot
2024-08-14 21:38     ` Al Viro
2024-08-15  2:49       ` Ma, Yu
2024-08-15  3:45         ` Al Viro
2024-08-15  8:34           ` Ma, Yu
2024-10-31  7:42           ` Mateusz Guzik
2024-10-31 10:14             ` Christian Brauner
2024-07-17 14:50   ` [PATCH v5 2/3] fs/file.c: conditionally clear full_fds Yu Ma
2024-07-17 14:50   ` [PATCH v5 3/3] fs/file.c: add fast path in find_next_fd() Yu Ma
2024-07-19 17:53     ` Mateusz Guzik
2024-07-20 12:57       ` Ma, Yu
2024-07-20 14:22         ` Mateusz Guzik
2024-08-06 13:48     ` kernel test robot
2024-07-22 15:02   ` [PATCH v5 0/3] fs/file.c: optimize the critical section of file_lock in Christian Brauner
2024-08-01 19:13     ` Al Viro
2024-08-02 11:04       ` Christian Brauner
2024-08-02 14:22         ` Al Viro
2024-08-05  6:56           ` Christian Brauner
2024-08-12  1:31             ` Ma, Yu
2024-08-12  2:40               ` Al Viro
2024-08-12 15:09                 ` Ma, Yu
2024-11-06 17:44                 ` Jan Kara
2024-11-06 17:59                   ` Al Viro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87a1279c-c5df-4f3b-936d-c9b8ed58f46e@intel.com \
    --to=yu.ma@intel.com \
    --cc=brauner@kernel.org \
    --cc=edumazet@google.com \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mjguzik@gmail.com \
    --cc=pan.deng@intel.com \
    --cc=tianyou.li@intel.com \
    --cc=tim.c.chen@intel.com \
    --cc=tim.c.chen@linux.intel.com \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®