From 71c78c869a25efbb515a19a545a29ef15bc2f8df Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 24 Aug 2021 09:59:07 +1000 Subject: [PATCH] writeback: avoid division by 0 in wb_update_dirty_ratelimit() Fixup patch "writeback: Fix bandwidth estimate for spiky workload" which introduced possibility of __wb_update_bandwidth() getting called at a moment when 'elapsed' evaluates to 0. Cc: Jan Kara Cc: Michael Stapelberg Cc: Wu Fengguang Signed-off-by: Andrew Morton Signed-off-by: Stephen Rothwell --- mm/page-writeback.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mm/page-writeback.c b/mm/page-writeback.c index eb55c8882db0..156f5888c09d 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -1336,11 +1336,19 @@ static void __wb_update_bandwidth(struct dirty_throttle_control *gdtc, { struct bdi_writeback *wb = gdtc->wb; unsigned long now = jiffies; - unsigned long elapsed = now - wb->bw_time_stamp; + unsigned long elapsed; unsigned long dirtied; unsigned long written; spin_lock(&wb->list_lock); + + /* + * Lockless checks for elapsed time are racy and delayed update after + * IO completion doesn't do it at all (to make sure written pages are + * accounted reasonably quickly). Make sure elapsed >= 1 to avoid + * division errors. + */ + elapsed = max(now - wb->bw_time_stamp, 1UL); dirtied = percpu_counter_read(&wb->stat[WB_DIRTIED]); written = percpu_counter_read(&wb->stat[WB_WRITTEN]); -- 2.50.1