diff options
Diffstat (limited to 'mm/page_alloc.c')
| -rw-r--r-- | mm/page_alloc.c | 197 |
1 files changed, 122 insertions, 75 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 253a450c400d..084a2de7e52a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/nodemask.h> | 37 | #include <linux/nodemask.h> |
| 38 | #include <linux/vmalloc.h> | 38 | #include <linux/vmalloc.h> |
| 39 | #include <linux/mempolicy.h> | 39 | #include <linux/mempolicy.h> |
| 40 | #include <linux/stop_machine.h> | ||
| 40 | 41 | ||
| 41 | #include <asm/tlbflush.h> | 42 | #include <asm/tlbflush.h> |
| 42 | #include <asm/div64.h> | 43 | #include <asm/div64.h> |
| @@ -83,8 +84,8 @@ EXPORT_SYMBOL(zone_table); | |||
| 83 | static char *zone_names[MAX_NR_ZONES] = { "DMA", "DMA32", "Normal", "HighMem" }; | 84 | static char *zone_names[MAX_NR_ZONES] = { "DMA", "DMA32", "Normal", "HighMem" }; |
| 84 | int min_free_kbytes = 1024; | 85 | int min_free_kbytes = 1024; |
| 85 | 86 | ||
| 86 | unsigned long __initdata nr_kernel_pages; | 87 | unsigned long __meminitdata nr_kernel_pages; |
| 87 | unsigned long __initdata nr_all_pages; | 88 | unsigned long __meminitdata nr_all_pages; |
| 88 | 89 | ||
| 89 | #ifdef CONFIG_DEBUG_VM | 90 | #ifdef CONFIG_DEBUG_VM |
| 90 | static int page_outside_zone_boundaries(struct zone *zone, struct page *page) | 91 | static int page_outside_zone_boundaries(struct zone *zone, struct page *page) |
| @@ -265,7 +266,7 @@ static inline void rmv_page_order(struct page *page) | |||
| 265 | * satisfies the following equation: | 266 | * satisfies the following equation: |
| 266 | * P = B & ~(1 << O) | 267 | * P = B & ~(1 << O) |
| 267 | * | 268 | * |
| 268 | * Assumption: *_mem_map is contigious at least up to MAX_ORDER | 269 | * Assumption: *_mem_map is contiguous at least up to MAX_ORDER |
| 269 | */ | 270 | */ |
| 270 | static inline struct page * | 271 | static inline struct page * |
| 271 | __page_find_buddy(struct page *page, unsigned long page_idx, unsigned int order) | 272 | __page_find_buddy(struct page *page, unsigned long page_idx, unsigned int order) |
| @@ -286,22 +287,27 @@ __find_combined_index(unsigned long page_idx, unsigned int order) | |||
| 286 | * we can do coalesce a page and its buddy if | 287 | * we can do coalesce a page and its buddy if |
| 287 | * (a) the buddy is not in a hole && | 288 | * (a) the buddy is not in a hole && |
| 288 | * (b) the buddy is in the buddy system && | 289 | * (b) the buddy is in the buddy system && |
| 289 | * (c) a page and its buddy have the same order. | 290 | * (c) a page and its buddy have the same order && |
| 291 | * (d) a page and its buddy are in the same zone. | ||
| 290 | * | 292 | * |
| 291 | * For recording whether a page is in the buddy system, we use PG_buddy. | 293 | * For recording whether a page is in the buddy system, we use PG_buddy. |
| 292 | * Setting, clearing, and testing PG_buddy is serialized by zone->lock. | 294 | * Setting, clearing, and testing PG_buddy is serialized by zone->lock. |
| 293 | * | 295 | * |
| 294 | * For recording page's order, we use page_private(page). | 296 | * For recording page's order, we use page_private(page). |
| 295 | */ | 297 | */ |
| 296 | static inline int page_is_buddy(struct page *page, int order) | 298 | static inline int page_is_buddy(struct page *page, struct page *buddy, |
| 299 | int order) | ||
| 297 | { | 300 | { |
| 298 | #ifdef CONFIG_HOLES_IN_ZONE | 301 | #ifdef CONFIG_HOLES_IN_ZONE |
| 299 | if (!pfn_valid(page_to_pfn(page))) | 302 | if (!pfn_valid(page_to_pfn(buddy))) |
| 300 | return 0; | 303 | return 0; |
| 301 | #endif | 304 | #endif |
| 302 | 305 | ||
| 303 | if (PageBuddy(page) && page_order(page) == order) { | 306 | if (page_zone_id(page) != page_zone_id(buddy)) |
| 304 | BUG_ON(page_count(page) != 0); | 307 | return 0; |
| 308 | |||
| 309 | if (PageBuddy(buddy) && page_order(buddy) == order) { | ||
| 310 | BUG_ON(page_count(buddy) != 0); | ||
| 305 | return 1; | 311 | return 1; |
| 306 | } | 312 | } |
| 307 | return 0; | 313 | return 0; |
| @@ -352,7 +358,7 @@ static inline void __free_one_page(struct page *page, | |||
| 352 | struct page *buddy; | 358 | struct page *buddy; |
| 353 | 359 | ||
| 354 | buddy = __page_find_buddy(page, page_idx, order); | 360 | buddy = __page_find_buddy(page, page_idx, order); |
| 355 | if (!page_is_buddy(buddy, order)) | 361 | if (!page_is_buddy(page, buddy, order)) |
| 356 | break; /* Move the buddy up one level. */ | 362 | break; /* Move the buddy up one level. */ |
| 357 | 363 | ||
| 358 | list_del(&buddy->lru); | 364 | list_del(&buddy->lru); |
| @@ -440,8 +446,8 @@ static void __free_pages_ok(struct page *page, unsigned int order) | |||
| 440 | 446 | ||
| 441 | arch_free_page(page, order); | 447 | arch_free_page(page, order); |
| 442 | if (!PageHighMem(page)) | 448 | if (!PageHighMem(page)) |
| 443 | mutex_debug_check_no_locks_freed(page_address(page), | 449 | debug_check_no_locks_freed(page_address(page), |
| 444 | PAGE_SIZE<<order); | 450 | PAGE_SIZE<<order); |
| 445 | 451 | ||
| 446 | for (i = 0 ; i < (1 << order) ; ++i) | 452 | for (i = 0 ; i < (1 << order) ; ++i) |
| 447 | reserved += free_pages_check(page + i); | 453 | reserved += free_pages_check(page + i); |
| @@ -951,8 +957,7 @@ restart: | |||
| 951 | goto got_pg; | 957 | goto got_pg; |
| 952 | 958 | ||
| 953 | do { | 959 | do { |
| 954 | if (cpuset_zone_allowed(*z, gfp_mask|__GFP_HARDWALL)) | 960 | wakeup_kswapd(*z, order); |
| 955 | wakeup_kswapd(*z, order); | ||
| 956 | } while (*(++z)); | 961 | } while (*(++z)); |
| 957 | 962 | ||
| 958 | /* | 963 | /* |
| @@ -1485,7 +1490,7 @@ void show_free_areas(void) | |||
| 1485 | } | 1490 | } |
| 1486 | 1491 | ||
| 1487 | for_each_zone(zone) { | 1492 | for_each_zone(zone) { |
| 1488 | unsigned long nr, flags, order, total = 0; | 1493 | unsigned long nr[MAX_ORDER], flags, order, total = 0; |
| 1489 | 1494 | ||
| 1490 | show_node(zone); | 1495 | show_node(zone); |
| 1491 | printk("%s: ", zone->name); | 1496 | printk("%s: ", zone->name); |
| @@ -1496,11 +1501,12 @@ void show_free_areas(void) | |||
| 1496 | 1501 | ||
| 1497 | spin_lock_irqsave(&zone->lock, flags); | 1502 | spin_lock_irqsave(&zone->lock, flags); |
| 1498 | for (order = 0; order < MAX_ORDER; order++) { | 1503 | for (order = 0; order < MAX_ORDER; order++) { |
| 1499 | nr = zone->free_area[order].nr_free; | 1504 | nr[order] = zone->free_area[order].nr_free; |
| 1500 | total += nr << order; | 1505 | total += nr[order] << order; |
| 1501 | printk("%lu*%lukB ", nr, K(1UL) << order); | ||
| 1502 | } | 1506 | } |
| 1503 | spin_unlock_irqrestore(&zone->lock, flags); | 1507 | spin_unlock_irqrestore(&zone->lock, flags); |
| 1508 | for (order = 0; order < MAX_ORDER; order++) | ||
| 1509 | printk("%lu*%lukB ", nr[order], K(1UL) << order); | ||
| 1504 | printk("= %lukB\n", K(total)); | 1510 | printk("= %lukB\n", K(total)); |
| 1505 | } | 1511 | } |
| 1506 | 1512 | ||
| @@ -1512,7 +1518,7 @@ void show_free_areas(void) | |||
| 1512 | * | 1518 | * |
| 1513 | * Add all populated zones of a node to the zonelist. | 1519 | * Add all populated zones of a node to the zonelist. |
| 1514 | */ | 1520 | */ |
| 1515 | static int __init build_zonelists_node(pg_data_t *pgdat, | 1521 | static int __meminit build_zonelists_node(pg_data_t *pgdat, |
| 1516 | struct zonelist *zonelist, int nr_zones, int zone_type) | 1522 | struct zonelist *zonelist, int nr_zones, int zone_type) |
| 1517 | { | 1523 | { |
| 1518 | struct zone *zone; | 1524 | struct zone *zone; |
| @@ -1548,7 +1554,7 @@ static inline int highest_zone(int zone_bits) | |||
| 1548 | 1554 | ||
| 1549 | #ifdef CONFIG_NUMA | 1555 | #ifdef CONFIG_NUMA |
| 1550 | #define MAX_NODE_LOAD (num_online_nodes()) | 1556 | #define MAX_NODE_LOAD (num_online_nodes()) |
| 1551 | static int __initdata node_load[MAX_NUMNODES]; | 1557 | static int __meminitdata node_load[MAX_NUMNODES]; |
| 1552 | /** | 1558 | /** |
| 1553 | * find_next_best_node - find the next node that should appear in a given node's fallback list | 1559 | * find_next_best_node - find the next node that should appear in a given node's fallback list |
| 1554 | * @node: node whose fallback list we're appending | 1560 | * @node: node whose fallback list we're appending |
| @@ -1563,7 +1569,7 @@ static int __initdata node_load[MAX_NUMNODES]; | |||
| 1563 | * on them otherwise. | 1569 | * on them otherwise. |
| 1564 | * It returns -1 if no node is found. | 1570 | * It returns -1 if no node is found. |
| 1565 | */ | 1571 | */ |
| 1566 | static int __init find_next_best_node(int node, nodemask_t *used_node_mask) | 1572 | static int __meminit find_next_best_node(int node, nodemask_t *used_node_mask) |
| 1567 | { | 1573 | { |
| 1568 | int n, val; | 1574 | int n, val; |
| 1569 | int min_val = INT_MAX; | 1575 | int min_val = INT_MAX; |
| @@ -1609,7 +1615,7 @@ static int __init find_next_best_node(int node, nodemask_t *used_node_mask) | |||
| 1609 | return best_node; | 1615 | return best_node; |
| 1610 | } | 1616 | } |
| 1611 | 1617 | ||
| 1612 | static void __init build_zonelists(pg_data_t *pgdat) | 1618 | static void __meminit build_zonelists(pg_data_t *pgdat) |
| 1613 | { | 1619 | { |
| 1614 | int i, j, k, node, local_node; | 1620 | int i, j, k, node, local_node; |
| 1615 | int prev_node, load; | 1621 | int prev_node, load; |
| @@ -1661,7 +1667,7 @@ static void __init build_zonelists(pg_data_t *pgdat) | |||
| 1661 | 1667 | ||
| 1662 | #else /* CONFIG_NUMA */ | 1668 | #else /* CONFIG_NUMA */ |
| 1663 | 1669 | ||
| 1664 | static void __init build_zonelists(pg_data_t *pgdat) | 1670 | static void __meminit build_zonelists(pg_data_t *pgdat) |
| 1665 | { | 1671 | { |
| 1666 | int i, j, k, node, local_node; | 1672 | int i, j, k, node, local_node; |
| 1667 | 1673 | ||
| @@ -1699,14 +1705,29 @@ static void __init build_zonelists(pg_data_t *pgdat) | |||
| 1699 | 1705 | ||
| 1700 | #endif /* CONFIG_NUMA */ | 1706 | #endif /* CONFIG_NUMA */ |
| 1701 | 1707 | ||
| 1702 | void __init build_all_zonelists(void) | 1708 | /* return values int ....just for stop_machine_run() */ |
| 1709 | static int __meminit __build_all_zonelists(void *dummy) | ||
| 1703 | { | 1710 | { |
| 1704 | int i; | 1711 | int nid; |
| 1712 | for_each_online_node(nid) | ||
| 1713 | build_zonelists(NODE_DATA(nid)); | ||
| 1714 | return 0; | ||
| 1715 | } | ||
| 1705 | 1716 | ||
| 1706 | for_each_online_node(i) | 1717 | void __meminit build_all_zonelists(void) |
| 1707 | build_zonelists(NODE_DATA(i)); | 1718 | { |
| 1708 | printk("Built %i zonelists\n", num_online_nodes()); | 1719 | if (system_state == SYSTEM_BOOTING) { |
| 1709 | cpuset_init_current_mems_allowed(); | 1720 | __build_all_zonelists(0); |
| 1721 | cpuset_init_current_mems_allowed(); | ||
| 1722 | } else { | ||
| 1723 | /* we have to stop all cpus to guaranntee there is no user | ||
| 1724 | of zonelist */ | ||
| 1725 | stop_machine_run(__build_all_zonelists, NULL, NR_CPUS); | ||
| 1726 | /* cpuset refresh routine should be here */ | ||
| 1727 | } | ||
| 1728 | vm_total_pages = nr_free_pagecache_pages(); | ||
| 1729 | printk("Built %i zonelists. Total pages: %ld\n", | ||
| 1730 | num_online_nodes(), vm_total_pages); | ||
| 1710 | } | 1731 | } |
| 1711 | 1732 | ||
| 1712 | /* | 1733 | /* |
| @@ -1722,7 +1743,8 @@ void __init build_all_zonelists(void) | |||
| 1722 | */ | 1743 | */ |
| 1723 | #define PAGES_PER_WAITQUEUE 256 | 1744 | #define PAGES_PER_WAITQUEUE 256 |
| 1724 | 1745 | ||
| 1725 | static inline unsigned long wait_table_size(unsigned long pages) | 1746 | #ifndef CONFIG_MEMORY_HOTPLUG |
| 1747 | static inline unsigned long wait_table_hash_nr_entries(unsigned long pages) | ||
| 1726 | { | 1748 | { |
| 1727 | unsigned long size = 1; | 1749 | unsigned long size = 1; |
| 1728 | 1750 | ||
| @@ -1740,6 +1762,29 @@ static inline unsigned long wait_table_size(unsigned long pages) | |||
| 1740 | 1762 | ||
| 1741 | return max(size, 4UL); | 1763 | return max(size, 4UL); |
| 1742 | } | 1764 | } |
| 1765 | #else | ||
| 1766 | /* | ||
| 1767 | * A zone's size might be changed by hot-add, so it is not possible to determine | ||
| 1768 | * a suitable size for its wait_table. So we use the maximum size now. | ||
| 1769 | * | ||
| 1770 | * The max wait table size = 4096 x sizeof(wait_queue_head_t). ie: | ||
| 1771 | * | ||
| 1772 | * i386 (preemption config) : 4096 x 16 = 64Kbyte. | ||
| 1773 | * ia64, x86-64 (no preemption): 4096 x 20 = 80Kbyte. | ||
| 1774 | * ia64, x86-64 (preemption) : 4096 x 24 = 96Kbyte. | ||
| 1775 | * | ||
| 1776 | * The maximum entries are prepared when a zone's memory is (512K + 256) pages | ||
| 1777 | * or more by the traditional way. (See above). It equals: | ||
| 1778 | * | ||
| 1779 | * i386, x86-64, powerpc(4K page size) : = ( 2G + 1M)byte. | ||
| 1780 | * ia64(16K page size) : = ( 8G + 4M)byte. | ||
| 1781 | * powerpc (64K page size) : = (32G +16M)byte. | ||
| 1782 | */ | ||
| 1783 | static inline unsigned long wait_table_hash_nr_entries(unsigned long pages) | ||
| 1784 | { | ||
| 1785 | return 4096UL; | ||
| 1786 | } | ||
| 1787 | #endif | ||
| 1743 | 1788 | ||
| 1744 | /* | 1789 | /* |
| 1745 | * This is an integer logarithm so that shifts can be used later | 1790 | * This is an integer logarithm so that shifts can be used later |
| @@ -1964,7 +2009,7 @@ static inline void free_zone_pagesets(int cpu) | |||
| 1964 | } | 2009 | } |
| 1965 | } | 2010 | } |
| 1966 | 2011 | ||
| 1967 | static int pageset_cpuup_callback(struct notifier_block *nfb, | 2012 | static int __cpuinit pageset_cpuup_callback(struct notifier_block *nfb, |
| 1968 | unsigned long action, | 2013 | unsigned long action, |
| 1969 | void *hcpu) | 2014 | void *hcpu) |
| 1970 | { | 2015 | { |
| @@ -1986,7 +2031,7 @@ static int pageset_cpuup_callback(struct notifier_block *nfb, | |||
| 1986 | return ret; | 2031 | return ret; |
| 1987 | } | 2032 | } |
| 1988 | 2033 | ||
| 1989 | static struct notifier_block pageset_notifier = | 2034 | static struct notifier_block __cpuinitdata pageset_notifier = |
| 1990 | { &pageset_cpuup_callback, NULL, 0 }; | 2035 | { &pageset_cpuup_callback, NULL, 0 }; |
| 1991 | 2036 | ||
| 1992 | void __init setup_per_cpu_pageset(void) | 2037 | void __init setup_per_cpu_pageset(void) |
| @@ -2005,23 +2050,46 @@ void __init setup_per_cpu_pageset(void) | |||
| 2005 | #endif | 2050 | #endif |
| 2006 | 2051 | ||
| 2007 | static __meminit | 2052 | static __meminit |
| 2008 | void zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages) | 2053 | int zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages) |
| 2009 | { | 2054 | { |
| 2010 | int i; | 2055 | int i; |
| 2011 | struct pglist_data *pgdat = zone->zone_pgdat; | 2056 | struct pglist_data *pgdat = zone->zone_pgdat; |
| 2057 | size_t alloc_size; | ||
| 2012 | 2058 | ||
| 2013 | /* | 2059 | /* |
| 2014 | * The per-page waitqueue mechanism uses hashed waitqueues | 2060 | * The per-page waitqueue mechanism uses hashed waitqueues |
| 2015 | * per zone. | 2061 | * per zone. |
| 2016 | */ | 2062 | */ |
| 2017 | zone->wait_table_size = wait_table_size(zone_size_pages); | 2063 | zone->wait_table_hash_nr_entries = |
| 2018 | zone->wait_table_bits = wait_table_bits(zone->wait_table_size); | 2064 | wait_table_hash_nr_entries(zone_size_pages); |
| 2019 | zone->wait_table = (wait_queue_head_t *) | 2065 | zone->wait_table_bits = |
| 2020 | alloc_bootmem_node(pgdat, zone->wait_table_size | 2066 | wait_table_bits(zone->wait_table_hash_nr_entries); |
| 2021 | * sizeof(wait_queue_head_t)); | 2067 | alloc_size = zone->wait_table_hash_nr_entries |
| 2068 | * sizeof(wait_queue_head_t); | ||
| 2069 | |||
| 2070 | if (system_state == SYSTEM_BOOTING) { | ||
| 2071 | zone->wait_table = (wait_queue_head_t *) | ||
| 2072 | alloc_bootmem_node(pgdat, alloc_size); | ||
| 2073 | } else { | ||
| 2074 | /* | ||
| 2075 | * This case means that a zone whose size was 0 gets new memory | ||
| 2076 | * via memory hot-add. | ||
| 2077 | * But it may be the case that a new node was hot-added. In | ||
| 2078 | * this case vmalloc() will not be able to use this new node's | ||
| 2079 | * memory - this wait_table must be initialized to use this new | ||
| 2080 | * node itself as well. | ||
| 2081 | * To use this new node's memory, further consideration will be | ||
| 2082 | * necessary. | ||
| 2083 | */ | ||
| 2084 | zone->wait_table = (wait_queue_head_t *)vmalloc(alloc_size); | ||
| 2085 | } | ||
| 2086 | if (!zone->wait_table) | ||
| 2087 | return -ENOMEM; | ||
| 2022 | 2088 | ||
| 2023 | for(i = 0; i < zone->wait_table_size; ++i) | 2089 | for(i = 0; i < zone->wait_table_hash_nr_entries; ++i) |
| 2024 | init_waitqueue_head(zone->wait_table + i); | 2090 | init_waitqueue_head(zone->wait_table + i); |
| 2091 | |||
| 2092 | return 0; | ||
| 2025 | } | 2093 | } |
| 2026 | 2094 | ||
| 2027 | static __meminit void zone_pcp_init(struct zone *zone) | 2095 | static __meminit void zone_pcp_init(struct zone *zone) |
| @@ -2043,12 +2111,15 @@ static __meminit void zone_pcp_init(struct zone *zone) | |||
| 2043 | zone->name, zone->present_pages, batch); | 2111 | zone->name, zone->present_pages, batch); |
| 2044 | } | 2112 | } |
| 2045 | 2113 | ||
| 2046 | static __meminit void init_currently_empty_zone(struct zone *zone, | 2114 | __meminit int init_currently_empty_zone(struct zone *zone, |
| 2047 | unsigned long zone_start_pfn, unsigned long size) | 2115 | unsigned long zone_start_pfn, |
| 2116 | unsigned long size) | ||
| 2048 | { | 2117 | { |
| 2049 | struct pglist_data *pgdat = zone->zone_pgdat; | 2118 | struct pglist_data *pgdat = zone->zone_pgdat; |
| 2050 | 2119 | int ret; | |
| 2051 | zone_wait_table_init(zone, size); | 2120 | ret = zone_wait_table_init(zone, size); |
| 2121 | if (ret) | ||
| 2122 | return ret; | ||
| 2052 | pgdat->nr_zones = zone_idx(zone) + 1; | 2123 | pgdat->nr_zones = zone_idx(zone) + 1; |
| 2053 | 2124 | ||
| 2054 | zone->zone_start_pfn = zone_start_pfn; | 2125 | zone->zone_start_pfn = zone_start_pfn; |
| @@ -2056,6 +2127,8 @@ static __meminit void init_currently_empty_zone(struct zone *zone, | |||
| 2056 | memmap_init(size, pgdat->node_id, zone_idx(zone), zone_start_pfn); | 2127 | memmap_init(size, pgdat->node_id, zone_idx(zone), zone_start_pfn); |
| 2057 | 2128 | ||
| 2058 | zone_init_free_lists(pgdat, zone, zone->spanned_pages); | 2129 | zone_init_free_lists(pgdat, zone, zone->spanned_pages); |
| 2130 | |||
| 2131 | return 0; | ||
| 2059 | } | 2132 | } |
| 2060 | 2133 | ||
| 2061 | /* | 2134 | /* |
| @@ -2064,12 +2137,13 @@ static __meminit void init_currently_empty_zone(struct zone *zone, | |||
| 2064 | * - mark all memory queues empty | 2137 | * - mark all memory queues empty |
| 2065 | * - clear the memory bitmaps | 2138 | * - clear the memory bitmaps |
| 2066 | */ | 2139 | */ |
| 2067 | static void __init free_area_init_core(struct pglist_data *pgdat, | 2140 | static void __meminit free_area_init_core(struct pglist_data *pgdat, |
| 2068 | unsigned long *zones_size, unsigned long *zholes_size) | 2141 | unsigned long *zones_size, unsigned long *zholes_size) |
| 2069 | { | 2142 | { |
| 2070 | unsigned long j; | 2143 | unsigned long j; |
| 2071 | int nid = pgdat->node_id; | 2144 | int nid = pgdat->node_id; |
| 2072 | unsigned long zone_start_pfn = pgdat->node_start_pfn; | 2145 | unsigned long zone_start_pfn = pgdat->node_start_pfn; |
| 2146 | int ret; | ||
| 2073 | 2147 | ||
| 2074 | pgdat_resize_init(pgdat); | 2148 | pgdat_resize_init(pgdat); |
| 2075 | pgdat->nr_zones = 0; | 2149 | pgdat->nr_zones = 0; |
| @@ -2111,7 +2185,8 @@ static void __init free_area_init_core(struct pglist_data *pgdat, | |||
| 2111 | continue; | 2185 | continue; |
| 2112 | 2186 | ||
| 2113 | zonetable_add(zone, nid, j, zone_start_pfn, size); | 2187 | zonetable_add(zone, nid, j, zone_start_pfn, size); |
| 2114 | init_currently_empty_zone(zone, zone_start_pfn, size); | 2188 | ret = init_currently_empty_zone(zone, zone_start_pfn, size); |
| 2189 | BUG_ON(ret); | ||
| 2115 | zone_start_pfn += size; | 2190 | zone_start_pfn += size; |
| 2116 | } | 2191 | } |
| 2117 | } | 2192 | } |
| @@ -2152,7 +2227,7 @@ static void __init alloc_node_mem_map(struct pglist_data *pgdat) | |||
| 2152 | #endif /* CONFIG_FLAT_NODE_MEM_MAP */ | 2227 | #endif /* CONFIG_FLAT_NODE_MEM_MAP */ |
| 2153 | } | 2228 | } |
| 2154 | 2229 | ||
| 2155 | void __init free_area_init_node(int nid, struct pglist_data *pgdat, | 2230 | void __meminit free_area_init_node(int nid, struct pglist_data *pgdat, |
| 2156 | unsigned long *zones_size, unsigned long node_start_pfn, | 2231 | unsigned long *zones_size, unsigned long node_start_pfn, |
| 2157 | unsigned long *zholes_size) | 2232 | unsigned long *zholes_size) |
| 2158 | { | 2233 | { |
| @@ -2804,42 +2879,14 @@ void *__init alloc_large_system_hash(const char *tablename, | |||
| 2804 | } | 2879 | } |
| 2805 | 2880 | ||
| 2806 | #ifdef CONFIG_OUT_OF_LINE_PFN_TO_PAGE | 2881 | #ifdef CONFIG_OUT_OF_LINE_PFN_TO_PAGE |
| 2807 | /* | ||
| 2808 | * pfn <-> page translation. out-of-line version. | ||
| 2809 | * (see asm-generic/memory_model.h) | ||
| 2810 | */ | ||
| 2811 | #if defined(CONFIG_FLATMEM) | ||
| 2812 | struct page *pfn_to_page(unsigned long pfn) | 2882 | struct page *pfn_to_page(unsigned long pfn) |
| 2813 | { | 2883 | { |
| 2814 | return mem_map + (pfn - ARCH_PFN_OFFSET); | 2884 | return __pfn_to_page(pfn); |
| 2815 | } | 2885 | } |
| 2816 | unsigned long page_to_pfn(struct page *page) | 2886 | unsigned long page_to_pfn(struct page *page) |
| 2817 | { | 2887 | { |
| 2818 | return (page - mem_map) + ARCH_PFN_OFFSET; | 2888 | return __page_to_pfn(page); |
| 2819 | } | ||
| 2820 | #elif defined(CONFIG_DISCONTIGMEM) | ||
| 2821 | struct page *pfn_to_page(unsigned long pfn) | ||
| 2822 | { | ||
| 2823 | int nid = arch_pfn_to_nid(pfn); | ||
| 2824 | return NODE_DATA(nid)->node_mem_map + arch_local_page_offset(pfn,nid); | ||
| 2825 | } | ||
| 2826 | unsigned long page_to_pfn(struct page *page) | ||
| 2827 | { | ||
| 2828 | struct pglist_data *pgdat = NODE_DATA(page_to_nid(page)); | ||
| 2829 | return (page - pgdat->node_mem_map) + pgdat->node_start_pfn; | ||
| 2830 | } | ||
| 2831 | #elif defined(CONFIG_SPARSEMEM) | ||
| 2832 | struct page *pfn_to_page(unsigned long pfn) | ||
| 2833 | { | ||
| 2834 | return __section_mem_map_addr(__pfn_to_section(pfn)) + pfn; | ||
| 2835 | } | ||
| 2836 | |||
| 2837 | unsigned long page_to_pfn(struct page *page) | ||
| 2838 | { | ||
| 2839 | long section_id = page_to_section(page); | ||
| 2840 | return page - __section_mem_map_addr(__nr_to_section(section_id)); | ||
| 2841 | } | 2889 | } |
| 2842 | #endif /* CONFIG_FLATMEM/DISCONTIGMME/SPARSEMEM */ | ||
| 2843 | EXPORT_SYMBOL(pfn_to_page); | 2890 | EXPORT_SYMBOL(pfn_to_page); |
| 2844 | EXPORT_SYMBOL(page_to_pfn); | 2891 | EXPORT_SYMBOL(page_to_pfn); |
| 2845 | #endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */ | 2892 | #endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */ |
