aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorNick Piggin <nickpiggin@yahoo.com.au>2005-11-28 16:44:03 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-28 17:42:24 -0500
commit3148890bfa4f36c9949871264e06ef4d449eeff9 (patch)
treef8d7b2498ec83883d1434abd9042ae8e6863bdb2 /mm
parentaa877b3dc9f2a1fdffac4ea36bee97c21db11a69 (diff)
[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>
Diffstat (limited to 'mm')
-rw-r--r--mm/page_alloc.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 1731236dec35..b257720edfc8 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -773,9 +773,12 @@ again:
773} 773}
774 774
775#define ALLOC_NO_WATERMARKS 0x01 /* don't check watermarks at all */ 775#define ALLOC_NO_WATERMARKS 0x01 /* don't check watermarks at all */
776#define ALLOC_HARDER 0x02 /* try to alloc harder */ 776#define ALLOC_WMARK_MIN 0x02 /* use pages_min watermark */
777#define ALLOC_HIGH 0x04 /* __GFP_HIGH set */ 777#define ALLOC_WMARK_LOW 0x04 /* use pages_low watermark */
778#define ALLOC_CPUSET 0x08 /* check for correct cpuset */ 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 */
779 782
780/* 783/*
781 * Return 1 if free pages are above 'mark'. This takes into account the order 784 * Return 1 if free pages are above 'mark'. This takes into account the order
@@ -830,7 +833,14 @@ get_page_from_freelist(gfp_t gfp_mask, unsigned int order,
830 continue; 833 continue;
831 834
832 if (!(alloc_flags & ALLOC_NO_WATERMARKS)) { 835 if (!(alloc_flags & ALLOC_NO_WATERMARKS)) {
833 if (!zone_watermark_ok(*z, order, (*z)->pages_low, 836 unsigned long mark;
837 if (alloc_flags & ALLOC_WMARK_MIN)
838 mark = (*z)->pages_min;
839 else if (alloc_flags & ALLOC_WMARK_LOW)
840 mark = (*z)->pages_low;
841 else
842 mark = (*z)->pages_high;
843 if (!zone_watermark_ok(*z, order, mark,
834 classzone_idx, alloc_flags)) 844 classzone_idx, alloc_flags))
835 continue; 845 continue;
836 } 846 }
@@ -871,7 +881,7 @@ restart:
871 } 881 }
872 882
873 page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order, 883 page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order,
874 zonelist, ALLOC_CPUSET); 884 zonelist, ALLOC_WMARK_LOW|ALLOC_CPUSET);
875 if (page) 885 if (page)
876 goto got_pg; 886 goto got_pg;
877 887
@@ -888,7 +898,7 @@ restart:
888 * cannot run direct reclaim, or if the caller has realtime scheduling 898 * cannot run direct reclaim, or if the caller has realtime scheduling
889 * policy. 899 * policy.
890 */ 900 */
891 alloc_flags = 0; 901 alloc_flags = ALLOC_WMARK_MIN;
892 if ((unlikely(rt_task(p)) && !in_interrupt()) || !wait) 902 if ((unlikely(rt_task(p)) && !in_interrupt()) || !wait)
893 alloc_flags |= ALLOC_HARDER; 903 alloc_flags |= ALLOC_HARDER;
894 if (gfp_mask & __GFP_HIGH) 904 if (gfp_mask & __GFP_HIGH)
@@ -959,7 +969,7 @@ rebalance:
959 * under heavy pressure. 969 * under heavy pressure.
960 */ 970 */
961 page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order, 971 page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order,
962 zonelist, ALLOC_CPUSET); 972 zonelist, ALLOC_WMARK_HIGH|ALLOC_CPUSET);
963 if (page) 973 if (page)
964 goto got_pg; 974 goto got_pg;
965 975