--- b/mm/page_alloc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff -puN mm/page_alloc.c~mm-absolute-floors-for-watermarks mm/page_alloc.c --- a/mm/page_alloc.c~mm-absolute-floors-for-watermarks 2015-02-17 11:19:48.470054562 -0800 +++ b/mm/page_alloc.c 2015-02-17 11:26:48.164983632 -0800 @@ -5739,6 +5739,14 @@ static void __setup_per_zone_wmarks(void } for_each_zone(zone) { + /* + * For very small zones (think 16MB ZONE_DMA on a 4TB system), + * proportionally distributing pages_min can lean to + * watermarks of 0. Give it an absolute floor so we always + * have at least a minimal watermark based on the size of the + * *zone*, not the system. + */ + unsigned long absolute_min = zone->managed_pages / 256; u64 tmp; spin_lock_irqsave(&zone->lock, flags); @@ -5766,7 +5774,8 @@ static void __setup_per_zone_wmarks(void */ zone->watermark[WMARK_MIN] = tmp; } - + zone->watermark[WMARK_MIN] = max(zone->watermark[WMARK_MIN], + absolute_min); zone->watermark[WMARK_LOW] = min_wmark_pages(zone) + (tmp >> 2); zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) + (tmp >> 1); _