Make ZONE_DMA optional in the page allocator Make ZONE_DMA configurable for the page allocator. We also check if we have only a single zone. If so then we do no longer use bits in the pageflags for the zone and then we can optimize various macros to give results at compile time. Siged-off-by: Christoph Lameter Index: linux-2.6.17-mm6/include/linux/mmzone.h =================================================================== --- linux-2.6.17-mm6.orig/include/linux/mmzone.h 2006-07-04 14:31:59.544971039 -0700 +++ linux-2.6.17-mm6/include/linux/mmzone.h 2006-07-04 15:27:18.534011885 -0700 @@ -88,6 +88,7 @@ struct per_cpu_pageset { #endif typedef enum { +#ifdef CONFIG_ZONE_DMA /* * ZONE_DMA is used when there are devices that are not able * to do DMA to all of addressable memory (ZONE_NORMAL). Then we @@ -116,6 +117,7 @@ typedef enum { */ ZONE_DMA32, #endif +#endif /* * Normal addressable memory is in ZONE_NORMAL. DMA operations can be * performed on pages in ZONE_NORMAL if the DMA devices support @@ -171,10 +173,18 @@ typedef enum { #define GFP_ZONETYPES 4 #define ZONES_SHIFT 2 #else +#ifdef CONFIG_DMA /* We only have ZONE_DMA and ZONE_NORMAL */ #define GFP_ZONEMASK 0x01 #define GFP_ZONETYPES 2 #define ZONES_SHIFT 1 +#else +/* We only have ZONE_NORMAL */ +#define GFP_ZONEMASK 0x00 +#define GFP_ZONETYPES 1 +#define ZONES_SHIFT 0 +#define SINGLE_ZONE 1 +#endif #endif #endif @@ -415,6 +425,26 @@ unsigned long __init node_memmap_size_by /* * zone_idx() returns 0 for the ZONE_DMA zone, 1 for the ZONE_NORMAL zone, etc. */ +#ifdef SINGLE_ZONE +#define zone_idx(zone) 0 + +static inline int populated_zone(struct zone *zone) +{ + return 1; +} + +static inline int is_normal_idx(int idx) +{ + return 1; +} + +static inline int is_normal(struct zone *zone) +{ + return 1; +} + +#else + #define zone_idx(zone) ((zone) - (zone)->zone_pgdat->node_zones) static inline int populated_zone(struct zone *zone) @@ -425,16 +455,21 @@ static inline int populated_zone(struct static inline int is_normal_idx(int idx) { return (idx == ZONE_NORMAL); -} static inline int is_normal(struct zone *zone) { return zone == zone->zone_pgdat->node_zones + ZONE_NORMAL; } +#endif + static inline int is_dma(struct zone *zone) { +#ifdef CONFIG_ZONE_DMA return zone == zone->zone_pgdat->node_zones + ZONE_DMA; +#else + return 0; +#endif } Index: linux-2.6.17-mm6/mm/page_alloc.c =================================================================== --- linux-2.6.17-mm6.orig/mm/page_alloc.c 2006-07-04 14:31:59.546924044 -0700 +++ linux-2.6.17-mm6/mm/page_alloc.c 2006-07-04 15:27:18.535964889 -0700 @@ -69,10 +69,12 @@ static void __free_pages_ok(struct page * don't need any ZONE_NORMAL reservation */ int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = { +#ifdef CONFIG_ZONE_DMA 256 #ifdef CONFIG_ZONE_DMA32 , 256 #endif +#endif #ifdef CONFIG_HIGHMEM , 32 #endif @@ -88,10 +90,12 @@ struct zone *zone_table[1 << ZONETABLE_S EXPORT_SYMBOL(zone_table); static char *zone_names[MAX_NR_ZONES] = { +#ifdef CONFIG_ZONE_DMA "DMA", #ifdef CONFIG_ZONE_DMA32 "DMA32", #endif +#endif "Normal", #ifdef CONFIG_HIGHMEM "HighMem" @@ -1485,8 +1489,10 @@ static inline int highest_zone(int zone_ if (zone_bits & (__force int)__GFP_DMA32) return ZONE_DMA32; #endif +#ifdef CONFIG_ZONE_DMA if ((zone_bits & (__force int)__GFP_DMA)) return ZONE_DMA; +#endif return ZONE_NORMAL; } Index: linux-2.6.17-mm6/mm/mempolicy.c =================================================================== --- linux-2.6.17-mm6.orig/mm/mempolicy.c 2006-07-03 13:47:22.620967283 -0700 +++ linux-2.6.17-mm6/mm/mempolicy.c 2006-07-04 15:27:18.536941392 -0700 @@ -103,9 +103,11 @@ static struct kmem_cache *sn_cache; #define PDprintk(fmt...) +#ifndef SINGLE_ZONE /* Highest zone. An specific allocation for a zone below that is not policied. */ int policy_zone = ZONE_DMA; +#endif struct mempolicy default_policy = { .refcnt = ATOMIC_INIT(1), /* never free it */ Index: linux-2.6.17-mm6/include/linux/mm.h =================================================================== --- linux-2.6.17-mm6.orig/include/linux/mm.h 2006-07-04 13:51:50.993618692 -0700 +++ linux-2.6.17-mm6/include/linux/mm.h 2006-07-04 15:29:33.410439840 -0700 @@ -469,16 +469,37 @@ void split_page(struct page *page, unsig #error SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED #endif +#ifdef SINGLE_ZONE +static inline unsigned long page_zonenum(struct page *page) +{ + return ZONE_NORMAL; +} + +static inline void set_page_zone(struct page *page, unsigned long zone) +{ + BUG_ON(zone); +} + +#else + #define ZONES_MASK ((1UL << ZONES_WIDTH) - 1) -#define NODES_MASK ((1UL << NODES_WIDTH) - 1) -#define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) -#define ZONETABLE_MASK ((1UL << ZONETABLE_SHIFT) - 1) static inline unsigned long page_zonenum(struct page *page) { return (page->flags >> ZONES_PGSHIFT) & ZONES_MASK; } +static inline void set_page_zone(struct page *page, unsigned long zone) +{ + page->flags &= ~(ZONES_MASK << ZONES_PGSHIFT); + page->flags |= (zone & ZONES_MASK) << ZONES_PGSHIFT; +} +#endif + +#define NODES_MASK ((1UL << NODES_WIDTH) - 1) +#define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) +#define ZONETABLE_MASK ((1UL << ZONETABLE_SHIFT) - 1) + struct zone; extern struct zone *zone_table[]; @@ -503,11 +524,6 @@ static inline unsigned long page_to_sect return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK; } -static inline void set_page_zone(struct page *page, unsigned long zone) -{ - page->flags &= ~(ZONES_MASK << ZONES_PGSHIFT); - page->flags |= (zone & ZONES_MASK) << ZONES_PGSHIFT; -} static inline void set_page_node(struct page *page, unsigned long node) { page->flags &= ~(NODES_MASK << NODES_PGSHIFT); Index: linux-2.6.17-mm6/include/linux/mempolicy.h =================================================================== --- linux-2.6.17-mm6.orig/include/linux/mempolicy.h 2006-07-03 13:47:21.727467854 -0700 +++ linux-2.6.17-mm6/include/linux/mempolicy.h 2006-07-04 15:27:18.537917894 -0700 @@ -162,12 +162,18 @@ extern struct zonelist *huge_zonelist(st unsigned long addr); extern unsigned slab_node(struct mempolicy *policy); +#ifdef SINGLE_ZONE +#define policy_zone ZONE_NORMAL +#else extern int policy_zone; +#endif static inline void check_highest_zone(int k) { +#ifndef SINGLE_ZONE if (k > policy_zone) policy_zone = k; +#endif } int do_migrate_pages(struct mm_struct *mm, Index: linux-2.6.17-mm6/include/linux/gfp.h =================================================================== --- linux-2.6.17-mm6.orig/include/linux/gfp.h 2006-07-04 14:41:53.820668198 -0700 +++ linux-2.6.17-mm6/include/linux/gfp.h 2006-07-04 15:33:07.401117400 -0700 @@ -11,7 +11,12 @@ struct vm_area_struct; * GFP bitmasks.. */ /* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low three bits) */ + +#ifdef CONFIG_ZONE_DMA #define __GFP_DMA ((__force gfp_t)0x01u) +#else +#define __GFP_DMA ((__force gfp_t)0x00) /* NORMAL is DMA */ +#endif #ifdef CONFIG_HIGHMEM #define __GFP_HIGHMEM ((__force gfp_t)0x02u)