aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mmzone.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/mmzone.h')
-rw-r--r--include/linux/mmzone.h68
1 files changed, 45 insertions, 23 deletions
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 5ed471b58f4f..9f22090df7dd 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -12,6 +12,7 @@
12#include <linux/threads.h> 12#include <linux/threads.h>
13#include <linux/numa.h> 13#include <linux/numa.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/seqlock.h>
15#include <asm/atomic.h> 16#include <asm/atomic.h>
16 17
17/* Free memory management - zoned buddy allocator. */ 18/* Free memory management - zoned buddy allocator. */
@@ -70,10 +71,11 @@ struct per_cpu_pageset {
70#endif 71#endif
71 72
72#define ZONE_DMA 0 73#define ZONE_DMA 0
73#define ZONE_NORMAL 1 74#define ZONE_DMA32 1
74#define ZONE_HIGHMEM 2 75#define ZONE_NORMAL 2
76#define ZONE_HIGHMEM 3
75 77
76#define MAX_NR_ZONES 3 /* Sync this with ZONES_SHIFT */ 78#define MAX_NR_ZONES 4 /* Sync this with ZONES_SHIFT */
77#define ZONES_SHIFT 2 /* ceil(log2(MAX_NR_ZONES)) */ 79#define ZONES_SHIFT 2 /* ceil(log2(MAX_NR_ZONES)) */
78 80
79 81
@@ -89,27 +91,18 @@ struct per_cpu_pageset {
89 * will be a maximum of 4 (2 ** 2) zonelists, for 3 modifiers there will 91 * will be a maximum of 4 (2 ** 2) zonelists, for 3 modifiers there will
90 * be 8 (2 ** 3) zonelists. GFP_ZONETYPES defines the number of possible 92 * be 8 (2 ** 3) zonelists. GFP_ZONETYPES defines the number of possible
91 * combinations of zone modifiers in "zone modifier space". 93 * combinations of zone modifiers in "zone modifier space".
94 *
95 * NOTE! Make sure this matches the zones in <linux/gfp.h>
92 */ 96 */
93#define GFP_ZONEMASK 0x03 97#define GFP_ZONEMASK 0x07
94/* 98#define GFP_ZONETYPES 5
95 * As an optimisation any zone modifier bits which are only valid when
96 * no other zone modifier bits are set (loners) should be placed in
97 * the highest order bits of this field. This allows us to reduce the
98 * extent of the zonelists thus saving space. For example in the case
99 * of three zone modifier bits, we could require up to eight zonelists.
100 * If the left most zone modifier is a "loner" then the highest valid
101 * zonelist would be four allowing us to allocate only five zonelists.
102 * Use the first form when the left most bit is not a "loner", otherwise
103 * use the second.
104 */
105/* #define GFP_ZONETYPES (GFP_ZONEMASK + 1) */ /* Non-loner */
106#define GFP_ZONETYPES ((GFP_ZONEMASK + 1) / 2 + 1) /* Loner */
107 99
108/* 100/*
109 * On machines where it is needed (eg PCs) we divide physical memory 101 * On machines where it is needed (eg PCs) we divide physical memory
110 * into multiple physical zones. On a PC we have 3 zones: 102 * into multiple physical zones. On a PC we have 4 zones:
111 * 103 *
112 * ZONE_DMA < 16 MB ISA DMA capable memory 104 * ZONE_DMA < 16 MB ISA DMA capable memory
105 * ZONE_DMA32 0 MB Empty
113 * ZONE_NORMAL 16-896 MB direct mapped by the kernel 106 * ZONE_NORMAL 16-896 MB direct mapped by the kernel
114 * ZONE_HIGHMEM > 896 MB only page cache and user processes 107 * ZONE_HIGHMEM > 896 MB only page cache and user processes
115 */ 108 */
@@ -137,6 +130,10 @@ struct zone {
137 * free areas of different sizes 130 * free areas of different sizes
138 */ 131 */
139 spinlock_t lock; 132 spinlock_t lock;
133#ifdef CONFIG_MEMORY_HOTPLUG
134 /* see spanned/present_pages for more description */
135 seqlock_t span_seqlock;
136#endif
140 struct free_area free_area[MAX_ORDER]; 137 struct free_area free_area[MAX_ORDER];
141 138
142 139
@@ -220,6 +217,16 @@ struct zone {
220 /* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */ 217 /* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
221 unsigned long zone_start_pfn; 218 unsigned long zone_start_pfn;
222 219
220 /*
221 * zone_start_pfn, spanned_pages and present_pages are all
222 * protected by span_seqlock. It is a seqlock because it has
223 * to be read outside of zone->lock, and it is done in the main
224 * allocator path. But, it is written quite infrequently.
225 *
226 * The lock is declared along with zone->lock because it is
227 * frequently read in proximity to zone->lock. It's good to
228 * give them a chance of being in the same cacheline.
229 */
223 unsigned long spanned_pages; /* total size, including holes */ 230 unsigned long spanned_pages; /* total size, including holes */
224 unsigned long present_pages; /* amount of memory (excluding holes) */ 231 unsigned long present_pages; /* amount of memory (excluding holes) */
225 232
@@ -273,6 +280,16 @@ typedef struct pglist_data {
273 struct page *node_mem_map; 280 struct page *node_mem_map;
274#endif 281#endif
275 struct bootmem_data *bdata; 282 struct bootmem_data *bdata;
283#ifdef CONFIG_MEMORY_HOTPLUG
284 /*
285 * Must be held any time you expect node_start_pfn, node_present_pages
286 * or node_spanned_pages stay constant. Holding this will also
287 * guarantee that any pfn_valid() stays that way.
288 *
289 * Nests above zone->lock and zone->size_seqlock.
290 */
291 spinlock_t node_size_lock;
292#endif
276 unsigned long node_start_pfn; 293 unsigned long node_start_pfn;
277 unsigned long node_present_pages; /* total number of physical pages */ 294 unsigned long node_present_pages; /* total number of physical pages */
278 unsigned long node_spanned_pages; /* total size of physical page 295 unsigned long node_spanned_pages; /* total size of physical page
@@ -293,6 +310,8 @@ typedef struct pglist_data {
293#endif 310#endif
294#define nid_page_nr(nid, pagenr) pgdat_page_nr(NODE_DATA(nid),(pagenr)) 311#define nid_page_nr(nid, pagenr) pgdat_page_nr(NODE_DATA(nid),(pagenr))
295 312
313#include <linux/memory_hotplug.h>
314
296extern struct pglist_data *pgdat_list; 315extern struct pglist_data *pgdat_list;
297 316
298void __get_zone_counts(unsigned long *active, unsigned long *inactive, 317void __get_zone_counts(unsigned long *active, unsigned long *inactive,
@@ -302,7 +321,7 @@ void get_zone_counts(unsigned long *active, unsigned long *inactive,
302void build_all_zonelists(void); 321void build_all_zonelists(void);
303void wakeup_kswapd(struct zone *zone, int order); 322void wakeup_kswapd(struct zone *zone, int order);
304int zone_watermark_ok(struct zone *z, int order, unsigned long mark, 323int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
305 int alloc_type, int can_try_harder, int gfp_high); 324 int classzone_idx, int alloc_flags);
306 325
307#ifdef CONFIG_HAVE_MEMORY_PRESENT 326#ifdef CONFIG_HAVE_MEMORY_PRESENT
308void memory_present(int nid, unsigned long start, unsigned long end); 327void memory_present(int nid, unsigned long start, unsigned long end);
@@ -406,7 +425,9 @@ int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, struct file *,
406 425
407#include <linux/topology.h> 426#include <linux/topology.h>
408/* Returns the number of the current Node. */ 427/* Returns the number of the current Node. */
428#ifndef numa_node_id
409#define numa_node_id() (cpu_to_node(raw_smp_processor_id())) 429#define numa_node_id() (cpu_to_node(raw_smp_processor_id()))
430#endif
410 431
411#ifndef CONFIG_NEED_MULTIPLE_NODES 432#ifndef CONFIG_NEED_MULTIPLE_NODES
412 433
@@ -426,12 +447,12 @@ extern struct pglist_data contig_page_data;
426#include <asm/sparsemem.h> 447#include <asm/sparsemem.h>
427#endif 448#endif
428 449
429#if BITS_PER_LONG == 32 || defined(ARCH_HAS_ATOMIC_UNSIGNED) 450#if BITS_PER_LONG == 32
430/* 451/*
431 * with 32 bit page->flags field, we reserve 8 bits for node/zone info. 452 * with 32 bit page->flags field, we reserve 9 bits for node/zone info.
432 * there are 3 zones (2 bits) and this leaves 8-2=6 bits for nodes. 453 * there are 4 zones (3 bits) and this leaves 9-3=6 bits for nodes.
433 */ 454 */
434#define FLAGS_RESERVED 8 455#define FLAGS_RESERVED 9
435 456
436#elif BITS_PER_LONG == 64 457#elif BITS_PER_LONG == 64
437/* 458/*
@@ -509,6 +530,7 @@ static inline struct mem_section *__nr_to_section(unsigned long nr)
509 return NULL; 530 return NULL;
510 return &mem_section[SECTION_NR_TO_ROOT(nr)][nr & SECTION_ROOT_MASK]; 531 return &mem_section[SECTION_NR_TO_ROOT(nr)][nr & SECTION_ROOT_MASK];
511} 532}
533extern int __section_nr(struct mem_section* ms);
512 534
513/* 535/*
514 * We use the lower bits of the mem_map pointer to store 536 * We use the lower bits of the mem_map pointer to store