Revert "ext4: remove ac->ac_found > sbi->s_mb_min_to_scan dead check in ext4_mb_check_limits"

This reverts commit 32c0869370.

The reverted commit was intended to remove a dead check however it was observed
that this check was actually being used to exit early instead of looping
sbi->s_mb_max_to_scan times when we are able to find a free extent bigger than
the goal extent. Due to this, a my performance tests (fsmark, parallel file
writes in a highly fragmented FS) were seeing a 2x-3x regression.

Example, the default value of the following variables is:

sbi->s_mb_max_to_scan = 200
sbi->s_mb_min_to_scan = 10

In ext4_mb_check_limits() if we find an extent smaller than goal, then we return
early and try again. This loop will go on until we have processed
sbi->s_mb_max_to_scan(=200) number of free extents at which point we exit and
just use whatever we have even if it is smaller than goal extent.

Now, the regression comes when we find an extent bigger than goal. Earlier, in
this case we would loop only sbi->s_mb_min_to_scan(=10) times and then just use
the bigger extent. However with commit 32c08693 that check was removed and hence
we would loop sbi->s_mb_max_to_scan(=200) times even though we have a big enough
free extent to satisfy the request. The only time we would exit early would be
when the free extent is *exactly* the size of our goal, which is pretty uncommon
occurrence and so we would almost always end up looping 200 times.

Hence, revert the commit by adding the check back to fix the regression. Also
add a comment to outline this policy.

Fixes: 32c0869370 ("ext4: remove ac->ac_found > sbi->s_mb_min_to_scan dead check in ext4_mb_check_limits")
Signed-off-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Reviewed-by: Kemeng Shi <shikemeng@huaweicloud.com>
Link: https://lore.kernel.org/r/ddcae9658e46880dfec2fb0aa61d01fb3353d202.1685449706.git.ojaswin@linux.ibm.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
Ojaswin Mujoo 2023-05-30 18:03:39 +05:30 коммит произвёл Theodore Ts'o
Родитель eb1f822c76
Коммит 3582e74599
1 изменённых файлов: 15 добавлений и 1 удалений

Просмотреть файл

@ -2062,7 +2062,7 @@ static void ext4_mb_check_limits(struct ext4_allocation_context *ac,
if (bex->fe_len < gex->fe_len) if (bex->fe_len < gex->fe_len)
return; return;
if (finish_group) if (finish_group || ac->ac_found > sbi->s_mb_min_to_scan)
ext4_mb_use_best_found(ac, e4b); ext4_mb_use_best_found(ac, e4b);
} }
@ -2074,6 +2074,20 @@ static void ext4_mb_check_limits(struct ext4_allocation_context *ac,
* in the context. Later, the best found extent will be used, if * in the context. Later, the best found extent will be used, if
* mballoc can't find good enough extent. * mballoc can't find good enough extent.
* *
* The algorithm used is roughly as follows:
*
* * If free extent found is exactly as big as goal, then
* stop the scan and use it immediately
*
* * If free extent found is smaller than goal, then keep retrying
* upto a max of sbi->s_mb_max_to_scan times (default 200). After
* that stop scanning and use whatever we have.
*
* * If free extent found is bigger than goal, then keep retrying
* upto a max of sbi->s_mb_min_to_scan times (default 10) before
* stopping the scan and using the extent.
*
*
* FIXME: real allocation policy is to be designed yet! * FIXME: real allocation policy is to be designed yet!
*/ */
static void ext4_mb_measure_extent(struct ext4_allocation_context *ac, static void ext4_mb_measure_extent(struct ext4_allocation_context *ac,