Skip to content

Commit 2cfed07

Browse files
minchanktorvalds
authored andcommitted
mm: fix free page check in zone_watermark_ok()
__zone_watermark_ok currently compares free_pages which is a signed type with z->lowmem_reserve[classzone_idx] which is unsigned which might lead to sign overflow if free_pages doesn't satisfy the given order (or it came as negative already) and then we rely on the following order loop to fix it (which doesn't work for order-0). Let's fix the type conversion and do not rely on the given value of free_pages or follow up fixups. This patch fixes it because "memory-hotplug: fix kswapd looping forever problem" depends on this. As benefit of this patch, it doesn't rely on the loop to exit __zone_watermark_ok in case of high order check and make the first test effective.(ie, if (free_pages <= min + lowmem_reserve)) Aaditya reported this problem when he test my hotplug patch. Reported-off-by: Aaditya Kumar <[email protected]> Tested-by: Aaditya Kumar <[email protected]> Signed-off-by: Aaditya Kumar <[email protected]> Signed-off-by: Minchan Kim <[email protected]> Cc: KOSAKI Motohiro <[email protected]> Cc: KAMEZAWA Hiroyuki <[email protected]> Cc: Mel Gorman <[email protected]> Reviewed-by: Michal Hocko <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent ee6f509 commit 2cfed07

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

mm/page_alloc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,7 @@ static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark,
15951595
{
15961596
/* free_pages my go negative - that's OK */
15971597
long min = mark;
1598+
long lowmem_reserve = z->lowmem_reserve[classzone_idx];
15981599
int o;
15991600

16001601
free_pages -= (1 << order) - 1;
@@ -1603,7 +1604,7 @@ static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark,
16031604
if (alloc_flags & ALLOC_HARDER)
16041605
min -= min / 4;
16051606

1606-
if (free_pages <= min + z->lowmem_reserve[classzone_idx])
1607+
if (free_pages <= min + lowmem_reserve)
16071608
return false;
16081609
for (o = 0; o < order; o++) {
16091610
/* At the next order, this order's pages become unavailable */

0 commit comments

Comments
 (0)