71 lines
2.9 KiB
Diff
71 lines
2.9 KiB
Diff
From cda8b1022f32bb7a917148f75f4641e7a5b3e729 Mon Sep 17 00:00:00 2001
|
|
From: Jinliang Zheng <alexjlzheng@tencent.com>
|
|
Date: Tue, 15 Apr 2025 17:02:32 +0800
|
|
Subject: mm: fix ratelimit_pages update error in dirty_ratio_handler()
|
|
|
|
In dirty_ratio_handler(), vm_dirty_bytes must be set to zero before
|
|
calling writeback_set_ratelimit(), as global_dirty_limits() always
|
|
prioritizes the value of vm_dirty_bytes.
|
|
|
|
It's domain_dirty_limits() that's relevant here, not node_dirty_ok:
|
|
|
|
dirty_ratio_handler
|
|
writeback_set_ratelimit
|
|
global_dirty_limits(&dirty_thresh) <- ratelimit_pages based on dirty_thresh
|
|
domain_dirty_limits
|
|
if (bytes) <- bytes = vm_dirty_bytes <--------+
|
|
thresh = f1(bytes) <- prioritizes vm_dirty_bytes |
|
|
else |
|
|
thresh = f2(ratio) |
|
|
ratelimit_pages = f3(dirty_thresh) |
|
|
vm_dirty_bytes = 0 <- it's late! ---------------------+
|
|
|
|
This causes ratelimit_pages to still use the value calculated based on
|
|
vm_dirty_bytes, which is wrong now.
|
|
|
|
|
|
The impact visible to userspace is difficult to capture directly because
|
|
there is no procfs/sysfs interface exported to user space. However, it
|
|
will have a real impact on the balance of dirty pages.
|
|
|
|
For example:
|
|
|
|
1. On default, we have vm_dirty_ratio=40, vm_dirty_bytes=0
|
|
|
|
2. echo 8192 > dirty_bytes, then vm_dirty_bytes=8192,
|
|
vm_dirty_ratio=0, and ratelimit_pages is calculated based on
|
|
vm_dirty_bytes now.
|
|
|
|
3. echo 20 > dirty_ratio, then since vm_dirty_bytes is not reset to
|
|
zero when writeback_set_ratelimit() -> global_dirty_limits() ->
|
|
domain_dirty_limits() is called, reallimit_pages is still calculated
|
|
based on vm_dirty_bytes instead of vm_dirty_ratio. This does not
|
|
conform to the actual intent of the user.
|
|
|
|
Link: https://lkml.kernel.org/r/20250415090232.7544-1-alexjlzheng@tencent.com
|
|
Fixes: 9d823e8f6b1b ("writeback: per task dirty rate limit")
|
|
Signed-off-by: Jinliang Zheng <alexjlzheng@tencent.com>
|
|
Reviewed-by: MengEn Sun <mengensun@tencent.com>
|
|
Cc: Andrea Righi <andrea@betterlinux.com>
|
|
Cc: Fenggaung Wu <fengguang.wu@intel.com>
|
|
Cc: Jinliang Zheng <alexjlzheng@tencent.com>
|
|
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
|
|
Cc: <stable@vger.kernel.org>
|
|
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|
---
|
|
mm/page-writeback.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
--- a/mm/page-writeback.c
|
|
+++ b/mm/page-writeback.c
|
|
@@ -520,8 +520,8 @@ static int dirty_ratio_handler(const str
|
|
|
|
ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
|
|
if (ret == 0 && write && vm_dirty_ratio != old_ratio) {
|
|
- writeback_set_ratelimit();
|
|
vm_dirty_bytes = 0;
|
|
+ writeback_set_ratelimit();
|
|
}
|
|
return ret;
|
|
}
|