diff options
Diffstat (limited to 'include/linux/mmzone.h')
-rw-r--r-- | include/linux/mmzone.h | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 6ef07de98d69..19860d317ec2 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
@@ -269,7 +269,9 @@ typedef struct pglist_data { | |||
269 | struct zone node_zones[MAX_NR_ZONES]; | 269 | struct zone node_zones[MAX_NR_ZONES]; |
270 | struct zonelist node_zonelists[GFP_ZONETYPES]; | 270 | struct zonelist node_zonelists[GFP_ZONETYPES]; |
271 | int nr_zones; | 271 | int nr_zones; |
272 | #ifdef CONFIG_FLAT_NODE_MEM_MAP | ||
272 | struct page *node_mem_map; | 273 | struct page *node_mem_map; |
274 | #endif | ||
273 | struct bootmem_data *bdata; | 275 | struct bootmem_data *bdata; |
274 | unsigned long node_start_pfn; | 276 | unsigned long node_start_pfn; |
275 | unsigned long node_present_pages; /* total number of physical pages */ | 277 | unsigned long node_present_pages; /* total number of physical pages */ |
@@ -284,7 +286,11 @@ typedef struct pglist_data { | |||
284 | 286 | ||
285 | #define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages) | 287 | #define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages) |
286 | #define node_spanned_pages(nid) (NODE_DATA(nid)->node_spanned_pages) | 288 | #define node_spanned_pages(nid) (NODE_DATA(nid)->node_spanned_pages) |
289 | #ifdef CONFIG_FLAT_NODE_MEM_MAP | ||
287 | #define pgdat_page_nr(pgdat, pagenr) ((pgdat)->node_mem_map + (pagenr)) | 290 | #define pgdat_page_nr(pgdat, pagenr) ((pgdat)->node_mem_map + (pagenr)) |
291 | #else | ||
292 | #define pgdat_page_nr(pgdat, pagenr) pfn_to_page((pgdat)->node_start_pfn + (pagenr)) | ||
293 | #endif | ||
288 | #define nid_page_nr(nid, pagenr) pgdat_page_nr(NODE_DATA(nid),(pagenr)) | 294 | #define nid_page_nr(nid, pagenr) pgdat_page_nr(NODE_DATA(nid),(pagenr)) |
289 | 295 | ||
290 | extern struct pglist_data *pgdat_list; | 296 | extern struct pglist_data *pgdat_list; |
@@ -416,6 +422,10 @@ extern struct pglist_data contig_page_data; | |||
416 | 422 | ||
417 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ | 423 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ |
418 | 424 | ||
425 | #ifdef CONFIG_SPARSEMEM | ||
426 | #include <asm/sparsemem.h> | ||
427 | #endif | ||
428 | |||
419 | #if BITS_PER_LONG == 32 || defined(ARCH_HAS_ATOMIC_UNSIGNED) | 429 | #if BITS_PER_LONG == 32 || defined(ARCH_HAS_ATOMIC_UNSIGNED) |
420 | /* | 430 | /* |
421 | * with 32 bit page->flags field, we reserve 8 bits for node/zone info. | 431 | * with 32 bit page->flags field, we reserve 8 bits for node/zone info. |
@@ -439,6 +449,92 @@ extern struct pglist_data contig_page_data; | |||
439 | #define early_pfn_to_nid(nid) (0UL) | 449 | #define early_pfn_to_nid(nid) (0UL) |
440 | #endif | 450 | #endif |
441 | 451 | ||
452 | #define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT) | ||
453 | #define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT) | ||
454 | |||
455 | #ifdef CONFIG_SPARSEMEM | ||
456 | |||
457 | /* | ||
458 | * SECTION_SHIFT #bits space required to store a section # | ||
459 | * | ||
460 | * PA_SECTION_SHIFT physical address to/from section number | ||
461 | * PFN_SECTION_SHIFT pfn to/from section number | ||
462 | */ | ||
463 | #define SECTIONS_SHIFT (MAX_PHYSMEM_BITS - SECTION_SIZE_BITS) | ||
464 | |||
465 | #define PA_SECTION_SHIFT (SECTION_SIZE_BITS) | ||
466 | #define PFN_SECTION_SHIFT (SECTION_SIZE_BITS - PAGE_SHIFT) | ||
467 | |||
468 | #define NR_MEM_SECTIONS (1UL << SECTIONS_SHIFT) | ||
469 | |||
470 | #define PAGES_PER_SECTION (1UL << PFN_SECTION_SHIFT) | ||
471 | #define PAGE_SECTION_MASK (~(PAGES_PER_SECTION-1)) | ||
472 | |||
473 | #if (MAX_ORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS | ||
474 | #error Allocator MAX_ORDER exceeds SECTION_SIZE | ||
475 | #endif | ||
476 | |||
477 | struct page; | ||
478 | struct mem_section { | ||
479 | struct page *section_mem_map; | ||
480 | }; | ||
481 | |||
482 | extern struct mem_section mem_section[NR_MEM_SECTIONS]; | ||
483 | |||
484 | /* | ||
485 | * Given a kernel address, find the home node of the underlying memory. | ||
486 | */ | ||
487 | #define kvaddr_to_nid(kaddr) pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT) | ||
488 | |||
489 | static inline struct mem_section *__pfn_to_section(unsigned long pfn) | ||
490 | { | ||
491 | return &mem_section[pfn_to_section_nr(pfn)]; | ||
492 | } | ||
493 | |||
494 | #define pfn_to_page(pfn) \ | ||
495 | ({ \ | ||
496 | unsigned long __pfn = (pfn); \ | ||
497 | __pfn_to_section(__pfn)->section_mem_map + __pfn; \ | ||
498 | }) | ||
499 | #define page_to_pfn(page) \ | ||
500 | ({ \ | ||
501 | page - mem_section[page_to_section(page)].section_mem_map; \ | ||
502 | }) | ||
503 | |||
504 | static inline int pfn_valid(unsigned long pfn) | ||
505 | { | ||
506 | if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS) | ||
507 | return 0; | ||
508 | return mem_section[pfn_to_section_nr(pfn)].section_mem_map != 0; | ||
509 | } | ||
510 | |||
511 | /* | ||
512 | * These are _only_ used during initialisation, therefore they | ||
513 | * can use __initdata ... They could have names to indicate | ||
514 | * this restriction. | ||
515 | */ | ||
516 | #ifdef CONFIG_NUMA | ||
517 | #define pfn_to_nid early_pfn_to_nid | ||
518 | #endif | ||
519 | |||
520 | #define pfn_to_pgdat(pfn) \ | ||
521 | ({ \ | ||
522 | NODE_DATA(pfn_to_nid(pfn)); \ | ||
523 | }) | ||
524 | |||
525 | #define early_pfn_valid(pfn) pfn_valid(pfn) | ||
526 | void sparse_init(void); | ||
527 | #else | ||
528 | #define sparse_init() do {} while (0) | ||
529 | #endif /* CONFIG_SPARSEMEM */ | ||
530 | |||
531 | #ifndef early_pfn_valid | ||
532 | #define early_pfn_valid(pfn) (1) | ||
533 | #endif | ||
534 | |||
535 | void memory_present(int nid, unsigned long start, unsigned long end); | ||
536 | unsigned long __init node_memmap_size_bytes(int, unsigned long, unsigned long); | ||
537 | |||
442 | #endif /* !__ASSEMBLY__ */ | 538 | #endif /* !__ASSEMBLY__ */ |
443 | #endif /* __KERNEL__ */ | 539 | #endif /* __KERNEL__ */ |
444 | #endif /* _LINUX_MMZONE_H */ | 540 | #endif /* _LINUX_MMZONE_H */ |