David Hildenbrand <david@xxxxxxxxxx> writes: > On 04.01.25 02:20, Stefan Roesch wrote: >> During testing it has been detected, that it is possible to get div by >> zero error in bdi_set_min_bytes. The error is caused by the function >> bdi_ratio_from_pages(). bdi_ratio_from_pages() calls >> global_dirty_limits. If the dirty threshold is 0, the div by zero is >> raised. This can happen if the root user is setting: >> echo 0 > /proc/sys/vm/dirty_ration. >> The following is a test case: >> echo 0 > /proc/sys/vm/dirty_ratio >> cd /sys/class/bdi/<device> >> echo 1 > strict_limit >> echo 8192 > min_bytes >> ==> error is raised. >> The problem is addressed by returning -EINVAL if dirty_ratio or >> dirty_bytes is set to 0. >> Reported-by: cheung wall <zzqq0103.hey@xxxxxxxxx> >> Closes: https://lore.kernel.org/linux-mm/87pll35yd0.fsf@xxxxxxxxxxxx/T/#t >> Signed-off-by: Stefan Roesch <shr@xxxxxxxxxxxx> >> --- >> mm/page-writeback.c | 2 ++ >> 1 file changed, 2 insertions(+) >> diff --git a/mm/page-writeback.c b/mm/page-writeback.c >> index d213ead95675..91aa7a5c0078 100644 >> --- a/mm/page-writeback.c >> +++ b/mm/page-writeback.c >> @@ -692,6 +692,8 @@ static unsigned long bdi_ratio_from_pages(unsigned long pages) >> unsigned long ratio; >> global_dirty_limits(&background_thresh, &dirty_thresh); >> + if (!dirty_thresh) >> + return -EINVAL; >> ratio = div64_u64(pages * 100ULL * BDI_RATIO_SCALE, dirty_thresh); >> return ratio; > > bdi_set_min_bytes() calls bdi_ratio_from_pages() and passes the result to > __bdi_set_min_ratio(). > > __bdi_set_min_ratio() expects an "unsigned int min_ratio". I assume this will > work because "max_ratio > 100 * BDI_RATIO_SCALE", but it is rather confusing ... > > Maybe we want something like: > > /* Use 101% to indicate "invalid" */ > #define BDI_RATIO_INVALID (101 * BDI_RATIO_SCALE) > > Or alternatively, just handle it in the callers of bdi_ratio_from_pages(), > checking for -EINVAL manually. David, I prefer the second option, its a bit easier to follow.