summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAndy Whitcroft <apw@shadowen.org>2006-06-23 02:03:01 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-23 07:42:45 -0700
commitcb2b95e1c6b56e3d2369d3a5f4bc97f4fa180683 (patch)
tree121d3fcd539f7d62887949840307ac26aadaa9e4 /include
parent6f0419e06a3b151ab616a31accdabef41dc2d1b0 (diff)
[PATCH] zone handle unaligned zone boundaries
The buddy allocator has a requirement that boundaries between contigious zones occur aligned with the the MAX_ORDER ranges. Where they do not we will incorrectly merge pages cross zone boundaries. This can lead to pages from the wrong zone being handed out. Originally the buddy allocator would check that buddies were in the same zone by referencing the zone start and end page frame numbers. This was removed as it became very expensive and the buddy allocator already made the assumption that zones boundaries were aligned. It is clear that not all configurations and architectures are honouring this alignment requirement. Therefore it seems safest to reintroduce support for non-aligned zone boundaries. This patch introduces a new check when considering a page a buddy it compares the zone_table index for the two pages and refuses to merge the pages where they do not match. The zone_table index is unique for each node/zone combination when FLATMEM/DISCONTIGMEM is enabled and for each section/zone combination when SPARSEMEM is enabled (a SPARSEMEM section is at least a MAX_ORDER size). Signed-off-by: Andy Whitcroft <apw@shadowen.org> Cc: Dave Hansen <haveblue@us.ibm.com> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Yasunori Goto <y-goto@jp.fujitsu.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/mm.h7
1 files changed, 5 insertions, 2 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h
index e2fa375e478..697c6bf248c 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -465,10 +465,13 @@ static inline unsigned long page_zonenum(struct page *page)
struct zone;
extern struct zone *zone_table[];
+static inline int page_zone_id(struct page *page)
+{
+ return (page->flags >> ZONETABLE_PGSHIFT) & ZONETABLE_MASK;
+}
static inline struct zone *page_zone(struct page *page)
{
- return zone_table[(page->flags >> ZONETABLE_PGSHIFT) &
- ZONETABLE_MASK];
+ return zone_table[page_zone_id(page)];
}
static inline unsigned long page_to_nid(struct page *page)