[PATCH] mm: __alloc_pages cleanup fix

I believe this patch is required to fix breakage in the asynch reclaim
watermark logic introduced by this patch:

http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=7fb1d9fca5c6e3b06773b69165a73f3fb786b8ee

Just some background of the watermark logic in case it isn't clear...
Basically what we have is this:

--- pages_high
|
| (a)
|
--- pages_low
|
| (b)
|
--- pages_min
|
| (c)
|
--- 0

Now when pages_low is reached, we want to kick asynch reclaim, which gives us
an interval of "b" before we must start synch reclaim, and gives kswapd an
interval of "a" before it need go back to sleep.

When pages_min is reached, normal allocators must enter synch reclaim, but
PF_MEMALLOC, ALLOC_HARDER, and ALLOC_HIGH (ie. atomic allocations, recursive
allocations, etc.) get access to varying amounts of the reserve "c".

Signed-off-by: Nick Piggin <npiggin@suse.de>
Cc: "Seth, Rohit" <rohit.seth@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Nick Piggin and committed by
Linus Torvalds
3148890b aa877b3d

+17 -7
+17 -7
mm/page_alloc.c
··· 773 } 774 775 #define ALLOC_NO_WATERMARKS 0x01 /* don't check watermarks at all */ 776 - #define ALLOC_HARDER 0x02 /* try to alloc harder */ 777 - #define ALLOC_HIGH 0x04 /* __GFP_HIGH set */ 778 - #define ALLOC_CPUSET 0x08 /* check for correct cpuset */ 779 780 /* 781 * Return 1 if free pages are above 'mark'. This takes into account the order ··· 833 continue; 834 835 if (!(alloc_flags & ALLOC_NO_WATERMARKS)) { 836 - if (!zone_watermark_ok(*z, order, (*z)->pages_low, 837 classzone_idx, alloc_flags)) 838 continue; 839 } ··· 881 } 882 883 page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order, 884 - zonelist, ALLOC_CPUSET); 885 if (page) 886 goto got_pg; 887 ··· 898 * cannot run direct reclaim, or if the caller has realtime scheduling 899 * policy. 900 */ 901 - alloc_flags = 0; 902 if ((unlikely(rt_task(p)) && !in_interrupt()) || !wait) 903 alloc_flags |= ALLOC_HARDER; 904 if (gfp_mask & __GFP_HIGH) ··· 969 * under heavy pressure. 970 */ 971 page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order, 972 - zonelist, ALLOC_CPUSET); 973 if (page) 974 goto got_pg; 975
··· 773 } 774 775 #define ALLOC_NO_WATERMARKS 0x01 /* don't check watermarks at all */ 776 + #define ALLOC_WMARK_MIN 0x02 /* use pages_min watermark */ 777 + #define ALLOC_WMARK_LOW 0x04 /* use pages_low watermark */ 778 + #define ALLOC_WMARK_HIGH 0x08 /* use pages_high watermark */ 779 + #define ALLOC_HARDER 0x10 /* try to alloc harder */ 780 + #define ALLOC_HIGH 0x20 /* __GFP_HIGH set */ 781 + #define ALLOC_CPUSET 0x40 /* check for correct cpuset */ 782 783 /* 784 * Return 1 if free pages are above 'mark'. This takes into account the order ··· 830 continue; 831 832 if (!(alloc_flags & ALLOC_NO_WATERMARKS)) { 833 + unsigned long mark; 834 + if (alloc_flags & ALLOC_WMARK_MIN) 835 + mark = (*z)->pages_min; 836 + else if (alloc_flags & ALLOC_WMARK_LOW) 837 + mark = (*z)->pages_low; 838 + else 839 + mark = (*z)->pages_high; 840 + if (!zone_watermark_ok(*z, order, mark, 841 classzone_idx, alloc_flags)) 842 continue; 843 } ··· 871 } 872 873 page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order, 874 + zonelist, ALLOC_WMARK_LOW|ALLOC_CPUSET); 875 if (page) 876 goto got_pg; 877 ··· 888 * cannot run direct reclaim, or if the caller has realtime scheduling 889 * policy. 890 */ 891 + alloc_flags = ALLOC_WMARK_MIN; 892 if ((unlikely(rt_task(p)) && !in_interrupt()) || !wait) 893 alloc_flags |= ALLOC_HARDER; 894 if (gfp_mask & __GFP_HIGH) ··· 959 * under heavy pressure. 960 */ 961 page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order, 962 + zonelist, ALLOC_WMARK_HIGH|ALLOC_CPUSET); 963 if (page) 964 goto got_pg; 965