mm, page_alloc: fix a division by zero error when boosting watermarks v2 [Linux 5.0]

mm, page_alloc: fix a division by zero error when boosting watermarks v2 [Linux 5.0]

This Linux kernel change "mm, page_alloc: fix a division by zero error when boosting watermarks v2" is included in the Linux 5.0 release. This change is authored by Mel Gorman <mgorman [at] techsingularity.net> on Wed Feb 20 22:19:49 2019 -0800. The commit for this change in Linux stable tree is 94b3334 (patch).

mm, page_alloc: fix a division by zero error when boosting watermarks v2

Yury Norov reported that an arm64 KVM instance could not boot since
after v5.0-rc1 and could addressed by reverting the patches

  1c30844d2dfe272d58c ("mm: reclaim small amounts of memory when an external
  73444bc4d8f92e46a20 ("mm, page_alloc: do not wake kswapd with zone lock held")

The problem is that a division by zero error is possible if boosting
occurs very early in boot if the system has very little memory.  This
patch avoids the division by zero error.

Link: http://lkml.kernel.org/r/[email protected]
Fixes: 1c30844d2dfe ("mm: reclaim small amounts of memory when an external fragmentation event occurs")
Signed-off-by: Mel Gorman <[email protected]>
Reported-by: Yury Norov <[email protected]>
Tested-by: Yury Norov <[email protected]>
Tested-by: Will Deacon <[email protected]>
Acked-by: Vlastimil Babka <[email protected]>
Cc: Andrea Arcangeli <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Michal Hocko <[email protected]>
Cc: Catalin Marinas <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>

There are 12 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 mm/page_alloc.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 7f79b78..0b9f577 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2170,6 +2170,18 @@ static inline void boost_watermark(struct zone *zone)

    max_boost = mult_frac(zone->_watermark[WMARK_HIGH],
            watermark_boost_factor, 10000);
+
+   /*
+    * high watermark may be uninitialised if fragmentation occurs
+    * very early in boot so do not boost. We do not fall
+    * through and boost by pageblock_nr_pages as failing
+    * allocations that early means that reclaim is not going
+    * to help and it may even be impossible to reclaim the
+    * boosted watermark resulting in a hang.
+    */
+   if (!max_boost)
+       return;
+
    max_boost = max(pageblock_nr_pages, max_boost);

    zone->watermark_boost = min(zone->watermark_boost + pageblock_nr_pages,

Leave a Reply

Your email address will not be published. Required fields are marked *