In __zone_watermark_ok, free and min are signed long type while z->lowmem_reserve[classzone_idx] is unsigned long type. So comparision of them could be wrong due to type conversion to unsigned although free_pages is minus value. It could return true instead of false in case of order-0 check so that kswapd could sleep forever. It means livelock because direct reclaimer loops forever until kswapd set zone->all_unreclaimable. Aaditya reported this problem when he test my hotplug patch. Reported-off-by: Aaditya Kumar <aaditya.kumar@xxxxxxxxxxx> Tested-by: Aaditya Kumar <aaditya.kumar@xxxxxxxxxxx> Signed-off-by: Aaditya Kumar <aaditya.kumar@xxxxxxxxxxx> Signed-off-by: Minchan Kim <minchan@xxxxxxxxxx> --- This patch isn't dependent with this series. It seems to be candidate for -stable but I'm not sure because of this part. So, pass the decision to akpm. " - It must fix a real bug that bothers people (not a, "This could be a problem..." type thing)." mm/page_alloc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index f17e6e4..627653c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1594,6 +1594,7 @@ static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark, { /* free_pages my go negative - that's OK */ long min = mark; + long lowmem_reserve = z->lowmem_reserve[classzone_idx]; int o; free_pages -= (1 << order) - 1; @@ -1602,7 +1603,7 @@ static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark, if (alloc_flags & ALLOC_HARDER) min -= min / 4; - if (free_pages <= min + z->lowmem_reserve[classzone_idx]) + if (free_pages <= min + lowmem_reserve) return false; for (o = 0; o < order; o++) { /* At the next order, this order's pages become unavailable */ -- 1.7.9.5 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>