diff options
Diffstat (limited to 'include/linux/mm.h')
-rw-r--r-- | include/linux/mm.h | 57 |
1 files changed, 36 insertions, 21 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index d538de901965..ab6e4974f379 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -396,7 +396,9 @@ void split_page(struct page *page, unsigned int order); | |||
396 | * We are going to use the flags for the page to node mapping if its in | 396 | * We are going to use the flags for the page to node mapping if its in |
397 | * there. This includes the case where there is no node, so it is implicit. | 397 | * there. This includes the case where there is no node, so it is implicit. |
398 | */ | 398 | */ |
399 | #define FLAGS_HAS_NODE (NODES_WIDTH > 0 || NODES_SHIFT == 0) | 399 | #if !(NODES_WIDTH > 0 || NODES_SHIFT == 0) |
400 | #define NODE_NOT_IN_PAGE_FLAGS | ||
401 | #endif | ||
400 | 402 | ||
401 | #ifndef PFN_SECTION_SHIFT | 403 | #ifndef PFN_SECTION_SHIFT |
402 | #define PFN_SECTION_SHIFT 0 | 404 | #define PFN_SECTION_SHIFT 0 |
@@ -411,13 +413,18 @@ void split_page(struct page *page, unsigned int order); | |||
411 | #define NODES_PGSHIFT (NODES_PGOFF * (NODES_WIDTH != 0)) | 413 | #define NODES_PGSHIFT (NODES_PGOFF * (NODES_WIDTH != 0)) |
412 | #define ZONES_PGSHIFT (ZONES_PGOFF * (ZONES_WIDTH != 0)) | 414 | #define ZONES_PGSHIFT (ZONES_PGOFF * (ZONES_WIDTH != 0)) |
413 | 415 | ||
414 | /* NODE:ZONE or SECTION:ZONE is used to lookup the zone from a page. */ | 416 | /* NODE:ZONE or SECTION:ZONE is used to ID a zone for the buddy allcator */ |
415 | #if FLAGS_HAS_NODE | 417 | #ifdef NODE_NOT_IN_PAGEFLAGS |
416 | #define ZONETABLE_SHIFT (NODES_SHIFT + ZONES_SHIFT) | 418 | #define ZONEID_SHIFT (SECTIONS_SHIFT + ZONES_SHIFT) |
417 | #else | 419 | #else |
418 | #define ZONETABLE_SHIFT (SECTIONS_SHIFT + ZONES_SHIFT) | 420 | #define ZONEID_SHIFT (NODES_SHIFT + ZONES_SHIFT) |
421 | #endif | ||
422 | |||
423 | #if ZONES_WIDTH > 0 | ||
424 | #define ZONEID_PGSHIFT ZONES_PGSHIFT | ||
425 | #else | ||
426 | #define ZONEID_PGSHIFT NODES_PGOFF | ||
419 | #endif | 427 | #endif |
420 | #define ZONETABLE_PGSHIFT ZONES_PGSHIFT | ||
421 | 428 | ||
422 | #if SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED | 429 | #if SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED |
423 | #error SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED | 430 | #error SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED |
@@ -426,23 +433,25 @@ void split_page(struct page *page, unsigned int order); | |||
426 | #define ZONES_MASK ((1UL << ZONES_WIDTH) - 1) | 433 | #define ZONES_MASK ((1UL << ZONES_WIDTH) - 1) |
427 | #define NODES_MASK ((1UL << NODES_WIDTH) - 1) | 434 | #define NODES_MASK ((1UL << NODES_WIDTH) - 1) |
428 | #define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) | 435 | #define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) |
429 | #define ZONETABLE_MASK ((1UL << ZONETABLE_SHIFT) - 1) | 436 | #define ZONEID_MASK ((1UL << ZONEID_SHIFT) - 1) |
430 | 437 | ||
431 | static inline enum zone_type page_zonenum(struct page *page) | 438 | static inline enum zone_type page_zonenum(struct page *page) |
432 | { | 439 | { |
433 | return (page->flags >> ZONES_PGSHIFT) & ZONES_MASK; | 440 | return (page->flags >> ZONES_PGSHIFT) & ZONES_MASK; |
434 | } | 441 | } |
435 | 442 | ||
436 | struct zone; | 443 | /* |
437 | extern struct zone *zone_table[]; | 444 | * The identification function is only used by the buddy allocator for |
438 | 445 | * determining if two pages could be buddies. We are not really | |
446 | * identifying a zone since we could be using a the section number | ||
447 | * id if we have not node id available in page flags. | ||
448 | * We guarantee only that it will return the same value for two | ||
449 | * combinable pages in a zone. | ||
450 | */ | ||
439 | static inline int page_zone_id(struct page *page) | 451 | static inline int page_zone_id(struct page *page) |
440 | { | 452 | { |
441 | return (page->flags >> ZONETABLE_PGSHIFT) & ZONETABLE_MASK; | 453 | BUILD_BUG_ON(ZONEID_PGSHIFT == 0 && ZONEID_MASK); |
442 | } | 454 | return (page->flags >> ZONEID_PGSHIFT) & ZONEID_MASK; |
443 | static inline struct zone *page_zone(struct page *page) | ||
444 | { | ||
445 | return zone_table[page_zone_id(page)]; | ||
446 | } | 455 | } |
447 | 456 | ||
448 | static inline unsigned long zone_to_nid(struct zone *zone) | 457 | static inline unsigned long zone_to_nid(struct zone *zone) |
@@ -454,13 +463,20 @@ static inline unsigned long zone_to_nid(struct zone *zone) | |||
454 | #endif | 463 | #endif |
455 | } | 464 | } |
456 | 465 | ||
466 | #ifdef NODE_NOT_IN_PAGE_FLAGS | ||
467 | extern unsigned long page_to_nid(struct page *page); | ||
468 | #else | ||
457 | static inline unsigned long page_to_nid(struct page *page) | 469 | static inline unsigned long page_to_nid(struct page *page) |
458 | { | 470 | { |
459 | if (FLAGS_HAS_NODE) | 471 | return (page->flags >> NODES_PGSHIFT) & NODES_MASK; |
460 | return (page->flags >> NODES_PGSHIFT) & NODES_MASK; | ||
461 | else | ||
462 | return zone_to_nid(page_zone(page)); | ||
463 | } | 472 | } |
473 | #endif | ||
474 | |||
475 | static inline struct zone *page_zone(struct page *page) | ||
476 | { | ||
477 | return &NODE_DATA(page_to_nid(page))->node_zones[page_zonenum(page)]; | ||
478 | } | ||
479 | |||
464 | static inline unsigned long page_to_section(struct page *page) | 480 | static inline unsigned long page_to_section(struct page *page) |
465 | { | 481 | { |
466 | return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK; | 482 | return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK; |
@@ -477,6 +493,7 @@ static inline void set_page_node(struct page *page, unsigned long node) | |||
477 | page->flags &= ~(NODES_MASK << NODES_PGSHIFT); | 493 | page->flags &= ~(NODES_MASK << NODES_PGSHIFT); |
478 | page->flags |= (node & NODES_MASK) << NODES_PGSHIFT; | 494 | page->flags |= (node & NODES_MASK) << NODES_PGSHIFT; |
479 | } | 495 | } |
496 | |||
480 | static inline void set_page_section(struct page *page, unsigned long section) | 497 | static inline void set_page_section(struct page *page, unsigned long section) |
481 | { | 498 | { |
482 | page->flags &= ~(SECTIONS_MASK << SECTIONS_PGSHIFT); | 499 | page->flags &= ~(SECTIONS_MASK << SECTIONS_PGSHIFT); |
@@ -947,8 +964,6 @@ extern void mem_init(void); | |||
947 | extern void show_mem(void); | 964 | extern void show_mem(void); |
948 | extern void si_meminfo(struct sysinfo * val); | 965 | extern void si_meminfo(struct sysinfo * val); |
949 | extern void si_meminfo_node(struct sysinfo *val, int nid); | 966 | extern void si_meminfo_node(struct sysinfo *val, int nid); |
950 | extern void zonetable_add(struct zone *zone, int nid, enum zone_type zid, | ||
951 | unsigned long pfn, unsigned long size); | ||
952 | 967 | ||
953 | #ifdef CONFIG_NUMA | 968 | #ifdef CONFIG_NUMA |
954 | extern void setup_per_cpu_pageset(void); | 969 | extern void setup_per_cpu_pageset(void); |