diff options
| author | Hao Jia <jiahao1@lixiang.com> | 2026-08-28 16:31:49 +0800 |
|---|---|---|
| committer | Andrew Morton <akpm@linux-foundation.org> | 2026-10-06 17:38:56 -0700 |
| commit | 59042a88efe1d5ddc457f192f4c6368909693133 (patch) | |
| tree | aa7e471166a32076f1f40308f61ccde16d71f1af /include/linux | |
| parent | 0e774fdb2ed62c9b3031bc16dcde68d05f24b2fd (diff) | |
zram: fix idle age_sec underflow in idle_store()
After commit 2e8ff2f51dde ("zram: use u32 for entry ac_time tracking"),
idle_store() computes the idle cutoff as:
cutoff = ktime_sub((u32)ktime_get_boottime_seconds(), age_sec);
Because the left operand is cast to u32, when age_sec exceeds the current
uptime the subtraction wraps modulo 2^32 and the huge result is
zero-extended into the s64 cutoff. mark_idle() then marks every entry as
idle instead of matching nothing. For instance, running
echo 86400 > /sys/block/zramX/idle
on a machine up for only two minutes marks all newly written pages idle
and hands them to idle writeback and recompression.
No slot can have been accessed before the system booted, so an age_sec
that reaches back past uptime cannot match any slot. Return early in that
case, without walking the table or taking any slot locks.
Track the cutoff as time64_t rather than ktime_t. Both cutoff and ac_time
are boot-time values in seconds, so a plain arithmetic comparison against
ac_time in mark_idle() is correct and no ktime helpers are needed.
Link: https://lore.kernel.org/20260828083149.45760-1-jiahao.kernel@gmail.com
Fixes: 2e8ff2f51dde ("zram: use u32 for entry ac_time tracking")
Signed-off-by: Hao Jia <jiahao1@lixiang.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Suggested-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Brian Geffon <bgeffon@google.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Minchan Kim <minchan@kernel.org>
Cc: <stable@vger.kernel.org>
Diffstat (limited to 'include/linux')
0 files changed, 0 insertions, 0 deletions
