diff options
Diffstat (limited to 'mm/page_alloc.c')
| -rw-r--r-- | mm/page_alloc.c | 749 |
1 files changed, 697 insertions, 52 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 9810f0a60db7..4f59d90b81e6 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -37,6 +37,8 @@ | |||
| 37 | #include <linux/vmalloc.h> | 37 | #include <linux/vmalloc.h> |
| 38 | #include <linux/mempolicy.h> | 38 | #include <linux/mempolicy.h> |
| 39 | #include <linux/stop_machine.h> | 39 | #include <linux/stop_machine.h> |
| 40 | #include <linux/sort.h> | ||
| 41 | #include <linux/pfn.h> | ||
| 40 | 42 | ||
| 41 | #include <asm/tlbflush.h> | 43 | #include <asm/tlbflush.h> |
| 42 | #include <asm/div64.h> | 44 | #include <asm/div64.h> |
| @@ -102,6 +104,38 @@ int min_free_kbytes = 1024; | |||
| 102 | 104 | ||
| 103 | unsigned long __meminitdata nr_kernel_pages; | 105 | unsigned long __meminitdata nr_kernel_pages; |
| 104 | unsigned long __meminitdata nr_all_pages; | 106 | unsigned long __meminitdata nr_all_pages; |
| 107 | static unsigned long __initdata dma_reserve; | ||
| 108 | |||
| 109 | #ifdef CONFIG_ARCH_POPULATES_NODE_MAP | ||
| 110 | /* | ||
| 111 | * MAX_ACTIVE_REGIONS determines the maxmimum number of distinct | ||
| 112 | * ranges of memory (RAM) that may be registered with add_active_range(). | ||
| 113 | * Ranges passed to add_active_range() will be merged if possible | ||
| 114 | * so the number of times add_active_range() can be called is | ||
| 115 | * related to the number of nodes and the number of holes | ||
| 116 | */ | ||
| 117 | #ifdef CONFIG_MAX_ACTIVE_REGIONS | ||
| 118 | /* Allow an architecture to set MAX_ACTIVE_REGIONS to save memory */ | ||
| 119 | #define MAX_ACTIVE_REGIONS CONFIG_MAX_ACTIVE_REGIONS | ||
| 120 | #else | ||
| 121 | #if MAX_NUMNODES >= 32 | ||
| 122 | /* If there can be many nodes, allow up to 50 holes per node */ | ||
| 123 | #define MAX_ACTIVE_REGIONS (MAX_NUMNODES*50) | ||
| 124 | #else | ||
| 125 | /* By default, allow up to 256 distinct regions */ | ||
| 126 | #define MAX_ACTIVE_REGIONS 256 | ||
| 127 | #endif | ||
| 128 | #endif | ||
| 129 | |||
| 130 | struct node_active_region __initdata early_node_map[MAX_ACTIVE_REGIONS]; | ||
| 131 | int __initdata nr_nodemap_entries; | ||
| 132 | unsigned long __initdata arch_zone_lowest_possible_pfn[MAX_NR_ZONES]; | ||
| 133 | unsigned long __initdata arch_zone_highest_possible_pfn[MAX_NR_ZONES]; | ||
| 134 | #ifdef CONFIG_MEMORY_HOTPLUG_RESERVE | ||
| 135 | unsigned long __initdata node_boundary_start_pfn[MAX_NUMNODES]; | ||
| 136 | unsigned long __initdata node_boundary_end_pfn[MAX_NUMNODES]; | ||
| 137 | #endif /* CONFIG_MEMORY_HOTPLUG_RESERVE */ | ||
| 138 | #endif /* CONFIG_ARCH_POPULATES_NODE_MAP */ | ||
| 105 | 139 | ||
| 106 | #ifdef CONFIG_DEBUG_VM | 140 | #ifdef CONFIG_DEBUG_VM |
| 107 | static int page_outside_zone_boundaries(struct zone *zone, struct page *page) | 141 | static int page_outside_zone_boundaries(struct zone *zone, struct page *page) |
| @@ -908,7 +942,7 @@ get_page_from_freelist(gfp_t gfp_mask, unsigned int order, | |||
| 908 | */ | 942 | */ |
| 909 | do { | 943 | do { |
| 910 | zone = *z; | 944 | zone = *z; |
| 911 | if (unlikely((gfp_mask & __GFP_THISNODE) && | 945 | if (unlikely(NUMA_BUILD && (gfp_mask & __GFP_THISNODE) && |
| 912 | zone->zone_pgdat != zonelist->zones[0]->zone_pgdat)) | 946 | zone->zone_pgdat != zonelist->zones[0]->zone_pgdat)) |
| 913 | break; | 947 | break; |
| 914 | if ((alloc_flags & ALLOC_CPUSET) && | 948 | if ((alloc_flags & ALLOC_CPUSET) && |
| @@ -1222,14 +1256,12 @@ unsigned int nr_free_pagecache_pages(void) | |||
| 1222 | { | 1256 | { |
| 1223 | return nr_free_zone_pages(gfp_zone(GFP_HIGHUSER)); | 1257 | return nr_free_zone_pages(gfp_zone(GFP_HIGHUSER)); |
| 1224 | } | 1258 | } |
| 1225 | #ifdef CONFIG_NUMA | 1259 | |
| 1226 | static void show_node(struct zone *zone) | 1260 | static inline void show_node(struct zone *zone) |
| 1227 | { | 1261 | { |
| 1228 | printk("Node %ld ", zone_to_nid(zone)); | 1262 | if (NUMA_BUILD) |
| 1263 | printk("Node %ld ", zone_to_nid(zone)); | ||
| 1229 | } | 1264 | } |
| 1230 | #else | ||
| 1231 | #define show_node(zone) do { } while (0) | ||
| 1232 | #endif | ||
| 1233 | 1265 | ||
| 1234 | void si_meminfo(struct sysinfo *val) | 1266 | void si_meminfo(struct sysinfo *val) |
| 1235 | { | 1267 | { |
| @@ -1271,34 +1303,30 @@ void si_meminfo_node(struct sysinfo *val, int nid) | |||
| 1271 | */ | 1303 | */ |
| 1272 | void show_free_areas(void) | 1304 | void show_free_areas(void) |
| 1273 | { | 1305 | { |
| 1274 | int cpu, temperature; | 1306 | int cpu; |
| 1275 | unsigned long active; | 1307 | unsigned long active; |
| 1276 | unsigned long inactive; | 1308 | unsigned long inactive; |
| 1277 | unsigned long free; | 1309 | unsigned long free; |
| 1278 | struct zone *zone; | 1310 | struct zone *zone; |
| 1279 | 1311 | ||
| 1280 | for_each_zone(zone) { | 1312 | for_each_zone(zone) { |
| 1281 | show_node(zone); | 1313 | if (!populated_zone(zone)) |
| 1282 | printk("%s per-cpu:", zone->name); | ||
| 1283 | |||
| 1284 | if (!populated_zone(zone)) { | ||
| 1285 | printk(" empty\n"); | ||
| 1286 | continue; | 1314 | continue; |
| 1287 | } else | 1315 | |
| 1288 | printk("\n"); | 1316 | show_node(zone); |
| 1317 | printk("%s per-cpu:\n", zone->name); | ||
| 1289 | 1318 | ||
| 1290 | for_each_online_cpu(cpu) { | 1319 | for_each_online_cpu(cpu) { |
| 1291 | struct per_cpu_pageset *pageset; | 1320 | struct per_cpu_pageset *pageset; |
| 1292 | 1321 | ||
| 1293 | pageset = zone_pcp(zone, cpu); | 1322 | pageset = zone_pcp(zone, cpu); |
| 1294 | 1323 | ||
| 1295 | for (temperature = 0; temperature < 2; temperature++) | 1324 | printk("CPU %4d: Hot: hi:%5d, btch:%4d usd:%4d " |
| 1296 | printk("cpu %d %s: high %d, batch %d used:%d\n", | 1325 | "Cold: hi:%5d, btch:%4d usd:%4d\n", |
| 1297 | cpu, | 1326 | cpu, pageset->pcp[0].high, |
| 1298 | temperature ? "cold" : "hot", | 1327 | pageset->pcp[0].batch, pageset->pcp[0].count, |
| 1299 | pageset->pcp[temperature].high, | 1328 | pageset->pcp[1].high, pageset->pcp[1].batch, |
| 1300 | pageset->pcp[temperature].batch, | 1329 | pageset->pcp[1].count); |
| 1301 | pageset->pcp[temperature].count); | ||
| 1302 | } | 1330 | } |
| 1303 | } | 1331 | } |
| 1304 | 1332 | ||
| @@ -1320,6 +1348,9 @@ void show_free_areas(void) | |||
| 1320 | for_each_zone(zone) { | 1348 | for_each_zone(zone) { |
| 1321 | int i; | 1349 | int i; |
| 1322 | 1350 | ||
| 1351 | if (!populated_zone(zone)) | ||
| 1352 | continue; | ||
| 1353 | |||
| 1323 | show_node(zone); | 1354 | show_node(zone); |
| 1324 | printk("%s" | 1355 | printk("%s" |
| 1325 | " free:%lukB" | 1356 | " free:%lukB" |
| @@ -1352,12 +1383,11 @@ void show_free_areas(void) | |||
| 1352 | for_each_zone(zone) { | 1383 | for_each_zone(zone) { |
| 1353 | unsigned long nr[MAX_ORDER], flags, order, total = 0; | 1384 | unsigned long nr[MAX_ORDER], flags, order, total = 0; |
| 1354 | 1385 | ||
| 1386 | if (!populated_zone(zone)) | ||
| 1387 | continue; | ||
| 1388 | |||
| 1355 | show_node(zone); | 1389 | show_node(zone); |
| 1356 | printk("%s: ", zone->name); | 1390 | printk("%s: ", zone->name); |
| 1357 | if (!populated_zone(zone)) { | ||
| 1358 | printk("empty\n"); | ||
| 1359 | continue; | ||
| 1360 | } | ||
| 1361 | 1391 | ||
| 1362 | spin_lock_irqsave(&zone->lock, flags); | 1392 | spin_lock_irqsave(&zone->lock, flags); |
| 1363 | for (order = 0; order < MAX_ORDER; order++) { | 1393 | for (order = 0; order < MAX_ORDER; order++) { |
| @@ -1561,7 +1591,7 @@ static int __meminit __build_all_zonelists(void *dummy) | |||
| 1561 | void __meminit build_all_zonelists(void) | 1591 | void __meminit build_all_zonelists(void) |
| 1562 | { | 1592 | { |
| 1563 | if (system_state == SYSTEM_BOOTING) { | 1593 | if (system_state == SYSTEM_BOOTING) { |
| 1564 | __build_all_zonelists(0); | 1594 | __build_all_zonelists(NULL); |
| 1565 | cpuset_init_current_mems_allowed(); | 1595 | cpuset_init_current_mems_allowed(); |
| 1566 | } else { | 1596 | } else { |
| 1567 | /* we have to stop all cpus to guaranntee there is no user | 1597 | /* we have to stop all cpus to guaranntee there is no user |
| @@ -1642,25 +1672,6 @@ static inline unsigned long wait_table_bits(unsigned long size) | |||
| 1642 | 1672 | ||
| 1643 | #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1)) | 1673 | #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1)) |
| 1644 | 1674 | ||
| 1645 | static void __init calculate_zone_totalpages(struct pglist_data *pgdat, | ||
| 1646 | unsigned long *zones_size, unsigned long *zholes_size) | ||
| 1647 | { | ||
| 1648 | unsigned long realtotalpages, totalpages = 0; | ||
| 1649 | enum zone_type i; | ||
| 1650 | |||
| 1651 | for (i = 0; i < MAX_NR_ZONES; i++) | ||
| 1652 | totalpages += zones_size[i]; | ||
| 1653 | pgdat->node_spanned_pages = totalpages; | ||
| 1654 | |||
| 1655 | realtotalpages = totalpages; | ||
| 1656 | if (zholes_size) | ||
| 1657 | for (i = 0; i < MAX_NR_ZONES; i++) | ||
| 1658 | realtotalpages -= zholes_size[i]; | ||
| 1659 | pgdat->node_present_pages = realtotalpages; | ||
| 1660 | printk(KERN_DEBUG "On node %d totalpages: %lu\n", pgdat->node_id, realtotalpages); | ||
| 1661 | } | ||
| 1662 | |||
| 1663 | |||
| 1664 | /* | 1675 | /* |
| 1665 | * Initially all pages are reserved - free ones are freed | 1676 | * Initially all pages are reserved - free ones are freed |
| 1666 | * up by free_all_bootmem() once the early boot process is | 1677 | * up by free_all_bootmem() once the early boot process is |
| @@ -1818,6 +1829,9 @@ static int __cpuinit process_zones(int cpu) | |||
| 1818 | 1829 | ||
| 1819 | for_each_zone(zone) { | 1830 | for_each_zone(zone) { |
| 1820 | 1831 | ||
| 1832 | if (!populated_zone(zone)) | ||
| 1833 | continue; | ||
| 1834 | |||
| 1821 | zone_pcp(zone, cpu) = kmalloc_node(sizeof(struct per_cpu_pageset), | 1835 | zone_pcp(zone, cpu) = kmalloc_node(sizeof(struct per_cpu_pageset), |
| 1822 | GFP_KERNEL, cpu_to_node(cpu)); | 1836 | GFP_KERNEL, cpu_to_node(cpu)); |
| 1823 | if (!zone_pcp(zone, cpu)) | 1837 | if (!zone_pcp(zone, cpu)) |
| @@ -1977,6 +1991,366 @@ __meminit int init_currently_empty_zone(struct zone *zone, | |||
| 1977 | return 0; | 1991 | return 0; |
| 1978 | } | 1992 | } |
| 1979 | 1993 | ||
| 1994 | #ifdef CONFIG_ARCH_POPULATES_NODE_MAP | ||
| 1995 | /* | ||
| 1996 | * Basic iterator support. Return the first range of PFNs for a node | ||
| 1997 | * Note: nid == MAX_NUMNODES returns first region regardless of node | ||
| 1998 | */ | ||
| 1999 | static int __init first_active_region_index_in_nid(int nid) | ||
| 2000 | { | ||
| 2001 | int i; | ||
| 2002 | |||
| 2003 | for (i = 0; i < nr_nodemap_entries; i++) | ||
| 2004 | if (nid == MAX_NUMNODES || early_node_map[i].nid == nid) | ||
| 2005 | return i; | ||
| 2006 | |||
| 2007 | return -1; | ||
| 2008 | } | ||
| 2009 | |||
| 2010 | /* | ||
| 2011 | * Basic iterator support. Return the next active range of PFNs for a node | ||
| 2012 | * Note: nid == MAX_NUMNODES returns next region regardles of node | ||
| 2013 | */ | ||
| 2014 | static int __init next_active_region_index_in_nid(int index, int nid) | ||
| 2015 | { | ||
| 2016 | for (index = index + 1; index < nr_nodemap_entries; index++) | ||
| 2017 | if (nid == MAX_NUMNODES || early_node_map[index].nid == nid) | ||
| 2018 | return index; | ||
| 2019 | |||
| 2020 | return -1; | ||
| 2021 | } | ||
| 2022 | |||
| 2023 | #ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID | ||
| 2024 | /* | ||
| 2025 | * Required by SPARSEMEM. Given a PFN, return what node the PFN is on. | ||
| 2026 | * Architectures may implement their own version but if add_active_range() | ||
| 2027 | * was used and there are no special requirements, this is a convenient | ||
| 2028 | * alternative | ||
| 2029 | */ | ||
| 2030 | int __init early_pfn_to_nid(unsigned long pfn) | ||
| 2031 | { | ||
| 2032 | int i; | ||
| 2033 | |||
| 2034 | for (i = 0; i < nr_nodemap_entries; i++) { | ||
| 2035 | unsigned long start_pfn = early_node_map[i].start_pfn; | ||
| 2036 | unsigned long end_pfn = early_node_map[i].end_pfn; | ||
| 2037 | |||
| 2038 | if (start_pfn <= pfn && pfn < end_pfn) | ||
| 2039 | return early_node_map[i].nid; | ||
| 2040 | } | ||
| 2041 | |||
| 2042 | return 0; | ||
| 2043 | } | ||
| 2044 | #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ | ||
| 2045 | |||
| 2046 | /* Basic iterator support to walk early_node_map[] */ | ||
| 2047 | #define for_each_active_range_index_in_nid(i, nid) \ | ||
| 2048 | for (i = first_active_region_index_in_nid(nid); i != -1; \ | ||
| 2049 | i = next_active_region_index_in_nid(i, nid)) | ||
| 2050 | |||
| 2051 | /** | ||
| 2052 | * free_bootmem_with_active_regions - Call free_bootmem_node for each active range | ||
| 2053 | * @nid: The node to free memory on. If MAX_NUMNODES, all nodes are freed | ||
| 2054 | * @max_low_pfn: The highest PFN that till be passed to free_bootmem_node | ||
| 2055 | * | ||
| 2056 | * If an architecture guarantees that all ranges registered with | ||
| 2057 | * add_active_ranges() contain no holes and may be freed, this | ||
| 2058 | * this function may be used instead of calling free_bootmem() manually. | ||
| 2059 | */ | ||
| 2060 | void __init free_bootmem_with_active_regions(int nid, | ||
| 2061 | unsigned long max_low_pfn) | ||
| 2062 | { | ||
| 2063 | int i; | ||
| 2064 | |||
| 2065 | for_each_active_range_index_in_nid(i, nid) { | ||
| 2066 | unsigned long size_pages = 0; | ||
| 2067 | unsigned long end_pfn = early_node_map[i].end_pfn; | ||
| 2068 | |||
| 2069 | if (early_node_map[i].start_pfn >= max_low_pfn) | ||
| 2070 | continue; | ||
| 2071 | |||
| 2072 | if (end_pfn > max_low_pfn) | ||
| 2073 | end_pfn = max_low_pfn; | ||
| 2074 | |||
| 2075 | size_pages = end_pfn - early_node_map[i].start_pfn; | ||
| 2076 | free_bootmem_node(NODE_DATA(early_node_map[i].nid), | ||
| 2077 | PFN_PHYS(early_node_map[i].start_pfn), | ||
| 2078 | size_pages << PAGE_SHIFT); | ||
| 2079 | } | ||
| 2080 | } | ||
| 2081 | |||
| 2082 | /** | ||
| 2083 | * sparse_memory_present_with_active_regions - Call memory_present for each active range | ||
| 2084 | * @nid: The node to call memory_present for. If MAX_NUMNODES, all nodes will be used | ||
| 2085 | * | ||
| 2086 | * If an architecture guarantees that all ranges registered with | ||
| 2087 | * add_active_ranges() contain no holes and may be freed, this | ||
| 2088 | * this function may be used instead of calling memory_present() manually. | ||
| 2089 | */ | ||
| 2090 | void __init sparse_memory_present_with_active_regions(int nid) | ||
| 2091 | { | ||
| 2092 | int i; | ||
| 2093 | |||
| 2094 | for_each_active_range_index_in_nid(i, nid) | ||
| 2095 | memory_present(early_node_map[i].nid, | ||
| 2096 | early_node_map[i].start_pfn, | ||
| 2097 | early_node_map[i].end_pfn); | ||
| 2098 | } | ||
| 2099 | |||
| 2100 | /** | ||
| 2101 | * push_node_boundaries - Push node boundaries to at least the requested boundary | ||
| 2102 | * @nid: The nid of the node to push the boundary for | ||
| 2103 | * @start_pfn: The start pfn of the node | ||
| 2104 | * @end_pfn: The end pfn of the node | ||
| 2105 | * | ||
| 2106 | * In reserve-based hot-add, mem_map is allocated that is unused until hotadd | ||
| 2107 | * time. Specifically, on x86_64, SRAT will report ranges that can potentially | ||
| 2108 | * be hotplugged even though no physical memory exists. This function allows | ||
| 2109 | * an arch to push out the node boundaries so mem_map is allocated that can | ||
| 2110 | * be used later. | ||
| 2111 | */ | ||
| 2112 | #ifdef CONFIG_MEMORY_HOTPLUG_RESERVE | ||
| 2113 | void __init push_node_boundaries(unsigned int nid, | ||
| 2114 | unsigned long start_pfn, unsigned long end_pfn) | ||
| 2115 | { | ||
| 2116 | printk(KERN_DEBUG "Entering push_node_boundaries(%u, %lu, %lu)\n", | ||
| 2117 | nid, start_pfn, end_pfn); | ||
| 2118 | |||
| 2119 | /* Initialise the boundary for this node if necessary */ | ||
| 2120 | if (node_boundary_end_pfn[nid] == 0) | ||
| 2121 | node_boundary_start_pfn[nid] = -1UL; | ||
| 2122 | |||
| 2123 | /* Update the boundaries */ | ||
| 2124 | if (node_boundary_start_pfn[nid] > start_pfn) | ||
| 2125 | node_boundary_start_pfn[nid] = start_pfn; | ||
| 2126 | if (node_boundary_end_pfn[nid] < end_pfn) | ||
| 2127 | node_boundary_end_pfn[nid] = end_pfn; | ||
| 2128 | } | ||
| 2129 | |||
| 2130 | /* If necessary, push the node boundary out for reserve hotadd */ | ||
| 2131 | static void __init account_node_boundary(unsigned int nid, | ||
| 2132 | unsigned long *start_pfn, unsigned long *end_pfn) | ||
| 2133 | { | ||
| 2134 | printk(KERN_DEBUG "Entering account_node_boundary(%u, %lu, %lu)\n", | ||
| 2135 | nid, *start_pfn, *end_pfn); | ||
| 2136 | |||
| 2137 | /* Return if boundary information has not been provided */ | ||
| 2138 | if (node_boundary_end_pfn[nid] == 0) | ||
| 2139 | return; | ||
| 2140 | |||
| 2141 | /* Check the boundaries and update if necessary */ | ||
| 2142 | if (node_boundary_start_pfn[nid] < *start_pfn) | ||
| 2143 | *start_pfn = node_boundary_start_pfn[nid]; | ||
| 2144 | if (node_boundary_end_pfn[nid] > *end_pfn) | ||
| 2145 | *end_pfn = node_boundary_end_pfn[nid]; | ||
| 2146 | } | ||
| 2147 | #else | ||
| 2148 | void __init push_node_boundaries(unsigned int nid, | ||
| 2149 | unsigned long start_pfn, unsigned long end_pfn) {} | ||
| 2150 | |||
| 2151 | static void __init account_node_boundary(unsigned int nid, | ||
| 2152 | unsigned long *start_pfn, unsigned long *end_pfn) {} | ||
| 2153 | #endif | ||
| 2154 | |||
| 2155 | |||
| 2156 | /** | ||
| 2157 | * get_pfn_range_for_nid - Return the start and end page frames for a node | ||
| 2158 | * @nid: The nid to return the range for. If MAX_NUMNODES, the min and max PFN are returned | ||
| 2159 | * @start_pfn: Passed by reference. On return, it will have the node start_pfn | ||
| 2160 | * @end_pfn: Passed by reference. On return, it will have the node end_pfn | ||
| 2161 | * | ||
| 2162 | * It returns the start and end page frame of a node based on information | ||
| 2163 | * provided by an arch calling add_active_range(). If called for a node | ||
| 2164 | * with no available memory, a warning is printed and the start and end | ||
| 2165 | * PFNs will be 0 | ||
| 2166 | */ | ||
| 2167 | void __init get_pfn_range_for_nid(unsigned int nid, | ||
| 2168 | unsigned long *start_pfn, unsigned long *end_pfn) | ||
| 2169 | { | ||
| 2170 | int i; | ||
| 2171 | *start_pfn = -1UL; | ||
| 2172 | *end_pfn = 0; | ||
| 2173 | |||
| 2174 | for_each_active_range_index_in_nid(i, nid) { | ||
| 2175 | *start_pfn = min(*start_pfn, early_node_map[i].start_pfn); | ||
| 2176 | *end_pfn = max(*end_pfn, early_node_map[i].end_pfn); | ||
| 2177 | } | ||
| 2178 | |||
| 2179 | if (*start_pfn == -1UL) { | ||
| 2180 | printk(KERN_WARNING "Node %u active with no memory\n", nid); | ||
| 2181 | *start_pfn = 0; | ||
| 2182 | } | ||
| 2183 | |||
| 2184 | /* Push the node boundaries out if requested */ | ||
| 2185 | account_node_boundary(nid, start_pfn, end_pfn); | ||
| 2186 | } | ||
| 2187 | |||
| 2188 | /* | ||
| 2189 | * Return the number of pages a zone spans in a node, including holes | ||
| 2190 | * present_pages = zone_spanned_pages_in_node() - zone_absent_pages_in_node() | ||
| 2191 | */ | ||
| 2192 | unsigned long __init zone_spanned_pages_in_node(int nid, | ||
| 2193 | unsigned long zone_type, | ||
| 2194 | unsigned long *ignored) | ||
| 2195 | { | ||
| 2196 | unsigned long node_start_pfn, node_end_pfn; | ||
| 2197 | unsigned long zone_start_pfn, zone_end_pfn; | ||
| 2198 | |||
| 2199 | /* Get the start and end of the node and zone */ | ||
| 2200 | get_pfn_range_for_nid(nid, &node_start_pfn, &node_end_pfn); | ||
| 2201 | zone_start_pfn = arch_zone_lowest_possible_pfn[zone_type]; | ||
| 2202 | zone_end_pfn = arch_zone_highest_possible_pfn[zone_type]; | ||
| 2203 | |||
| 2204 | /* Check that this node has pages within the zone's required range */ | ||
| 2205 | if (zone_end_pfn < node_start_pfn || zone_start_pfn > node_end_pfn) | ||
| 2206 | return 0; | ||
| 2207 | |||
| 2208 | /* Move the zone boundaries inside the node if necessary */ | ||
| 2209 | zone_end_pfn = min(zone_end_pfn, node_end_pfn); | ||
| 2210 | zone_start_pfn = max(zone_start_pfn, node_start_pfn); | ||
| 2211 | |||
| 2212 | /* Return the spanned pages */ | ||
| 2213 | return zone_end_pfn - zone_start_pfn; | ||
| 2214 | } | ||
| 2215 | |||
| 2216 | /* | ||
| 2217 | * Return the number of holes in a range on a node. If nid is MAX_NUMNODES, | ||
| 2218 | * then all holes in the requested range will be accounted for | ||
| 2219 | */ | ||
| 2220 | unsigned long __init __absent_pages_in_range(int nid, | ||
| 2221 | unsigned long range_start_pfn, | ||
| 2222 | unsigned long range_end_pfn) | ||
| 2223 | { | ||
| 2224 | int i = 0; | ||
| 2225 | unsigned long prev_end_pfn = 0, hole_pages = 0; | ||
| 2226 | unsigned long start_pfn; | ||
| 2227 | |||
| 2228 | /* Find the end_pfn of the first active range of pfns in the node */ | ||
| 2229 | i = first_active_region_index_in_nid(nid); | ||
| 2230 | if (i == -1) | ||
| 2231 | return 0; | ||
| 2232 | |||
| 2233 | /* Account for ranges before physical memory on this node */ | ||
| 2234 | if (early_node_map[i].start_pfn > range_start_pfn) | ||
| 2235 | hole_pages = early_node_map[i].start_pfn - range_start_pfn; | ||
| 2236 | |||
| 2237 | prev_end_pfn = early_node_map[i].start_pfn; | ||
| 2238 | |||
| 2239 | /* Find all holes for the zone within the node */ | ||
| 2240 | for (; i != -1; i = next_active_region_index_in_nid(i, nid)) { | ||
| 2241 | |||
| 2242 | /* No need to continue if prev_end_pfn is outside the zone */ | ||
| 2243 | if (prev_end_pfn >= range_end_pfn) | ||
| 2244 | break; | ||
| 2245 | |||
| 2246 | /* Make sure the end of the zone is not within the hole */ | ||
| 2247 | start_pfn = min(early_node_map[i].start_pfn, range_end_pfn); | ||
| 2248 | prev_end_pfn = max(prev_end_pfn, range_start_pfn); | ||
| 2249 | |||
| 2250 | /* Update the hole size cound and move on */ | ||
| 2251 | if (start_pfn > range_start_pfn) { | ||
| 2252 | BUG_ON(prev_end_pfn > start_pfn); | ||
| 2253 | hole_pages += start_pfn - prev_end_pfn; | ||
| 2254 | } | ||
| 2255 | prev_end_pfn = early_node_map[i].end_pfn; | ||
| 2256 | } | ||
| 2257 | |||
| 2258 | /* Account for ranges past physical memory on this node */ | ||
| 2259 | if (range_end_pfn > prev_end_pfn) | ||
| 2260 | hole_pages = range_end_pfn - | ||
| 2261 | max(range_start_pfn, prev_end_pfn); | ||
| 2262 | |||
| 2263 | return hole_pages; | ||
| 2264 | } | ||
| 2265 | |||
| 2266 | /** | ||
| 2267 | * absent_pages_in_range - Return number of page frames in holes within a range | ||
| 2268 | * @start_pfn: The start PFN to start searching for holes | ||
| 2269 | * @end_pfn: The end PFN to stop searching for holes | ||
| 2270 | * | ||
| 2271 | * It returns the number of pages frames in memory holes within a range | ||
| 2272 | */ | ||
| 2273 | unsigned long __init absent_pages_in_range(unsigned long start_pfn, | ||
| 2274 | unsigned long end_pfn) | ||
| 2275 | { | ||
| 2276 | return __absent_pages_in_range(MAX_NUMNODES, start_pfn, end_pfn); | ||
| 2277 | } | ||
| 2278 | |||
| 2279 | /* Return the number of page frames in holes in a zone on a node */ | ||
| 2280 | unsigned long __init zone_absent_pages_in_node(int nid, | ||
| 2281 | unsigned long zone_type, | ||
| 2282 | unsigned long *ignored) | ||
| 2283 | { | ||
| 2284 | unsigned long node_start_pfn, node_end_pfn; | ||
| 2285 | unsigned long zone_start_pfn, zone_end_pfn; | ||
| 2286 | |||
| 2287 | get_pfn_range_for_nid(nid, &node_start_pfn, &node_end_pfn); | ||
| 2288 | zone_start_pfn = max(arch_zone_lowest_possible_pfn[zone_type], | ||
| 2289 | node_start_pfn); | ||
| 2290 | zone_end_pfn = min(arch_zone_highest_possible_pfn[zone_type], | ||
| 2291 | node_end_pfn); | ||
| 2292 | |||
| 2293 | return __absent_pages_in_range(nid, zone_start_pfn, zone_end_pfn); | ||
| 2294 | } | ||
| 2295 | |||
| 2296 | /* Return the zone index a PFN is in */ | ||
| 2297 | int memmap_zone_idx(struct page *lmem_map) | ||
| 2298 | { | ||
| 2299 | int i; | ||
| 2300 | unsigned long phys_addr = virt_to_phys(lmem_map); | ||
| 2301 | unsigned long pfn = phys_addr >> PAGE_SHIFT; | ||
| 2302 | |||
| 2303 | for (i = 0; i < MAX_NR_ZONES; i++) | ||
| 2304 | if (pfn < arch_zone_highest_possible_pfn[i]) | ||
| 2305 | break; | ||
| 2306 | |||
| 2307 | return i; | ||
| 2308 | } | ||
| 2309 | #else | ||
| 2310 | static inline unsigned long zone_spanned_pages_in_node(int nid, | ||
| 2311 | unsigned long zone_type, | ||
| 2312 | unsigned long *zones_size) | ||
| 2313 | { | ||
| 2314 | return zones_size[zone_type]; | ||
| 2315 | } | ||
| 2316 | |||
| 2317 | static inline unsigned long zone_absent_pages_in_node(int nid, | ||
| 2318 | unsigned long zone_type, | ||
| 2319 | unsigned long *zholes_size) | ||
| 2320 | { | ||
| 2321 | if (!zholes_size) | ||
| 2322 | return 0; | ||
| 2323 | |||
| 2324 | return zholes_size[zone_type]; | ||
| 2325 | } | ||
| 2326 | |||
| 2327 | static inline int memmap_zone_idx(struct page *lmem_map) | ||
| 2328 | { | ||
| 2329 | return MAX_NR_ZONES; | ||
| 2330 | } | ||
| 2331 | #endif | ||
| 2332 | |||
| 2333 | static void __init calculate_node_totalpages(struct pglist_data *pgdat, | ||
| 2334 | unsigned long *zones_size, unsigned long *zholes_size) | ||
| 2335 | { | ||
| 2336 | unsigned long realtotalpages, totalpages = 0; | ||
| 2337 | enum zone_type i; | ||
| 2338 | |||
| 2339 | for (i = 0; i < MAX_NR_ZONES; i++) | ||
| 2340 | totalpages += zone_spanned_pages_in_node(pgdat->node_id, i, | ||
| 2341 | zones_size); | ||
| 2342 | pgdat->node_spanned_pages = totalpages; | ||
| 2343 | |||
| 2344 | realtotalpages = totalpages; | ||
| 2345 | for (i = 0; i < MAX_NR_ZONES; i++) | ||
| 2346 | realtotalpages -= | ||
| 2347 | zone_absent_pages_in_node(pgdat->node_id, i, | ||
| 2348 | zholes_size); | ||
| 2349 | pgdat->node_present_pages = realtotalpages; | ||
| 2350 | printk(KERN_DEBUG "On node %d totalpages: %lu\n", pgdat->node_id, | ||
| 2351 | realtotalpages); | ||
| 2352 | } | ||
| 2353 | |||
| 1980 | /* | 2354 | /* |
| 1981 | * Set up the zone data structures: | 2355 | * Set up the zone data structures: |
| 1982 | * - mark all pages reserved | 2356 | * - mark all pages reserved |
| @@ -1998,11 +2372,34 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat, | |||
| 1998 | 2372 | ||
| 1999 | for (j = 0; j < MAX_NR_ZONES; j++) { | 2373 | for (j = 0; j < MAX_NR_ZONES; j++) { |
| 2000 | struct zone *zone = pgdat->node_zones + j; | 2374 | struct zone *zone = pgdat->node_zones + j; |
| 2001 | unsigned long size, realsize; | 2375 | unsigned long size, realsize, memmap_pages; |
| 2002 | 2376 | ||
| 2003 | realsize = size = zones_size[j]; | 2377 | size = zone_spanned_pages_in_node(nid, j, zones_size); |
| 2004 | if (zholes_size) | 2378 | realsize = size - zone_absent_pages_in_node(nid, j, |
| 2005 | realsize -= zholes_size[j]; | 2379 | zholes_size); |
| 2380 | |||
| 2381 | /* | ||
| 2382 | * Adjust realsize so that it accounts for how much memory | ||
| 2383 | * is used by this zone for memmap. This affects the watermark | ||
| 2384 | * and per-cpu initialisations | ||
| 2385 | */ | ||
| 2386 | memmap_pages = (size * sizeof(struct page)) >> PAGE_SHIFT; | ||
| 2387 | if (realsize >= memmap_pages) { | ||
| 2388 | realsize -= memmap_pages; | ||
| 2389 | printk(KERN_DEBUG | ||
| 2390 | " %s zone: %lu pages used for memmap\n", | ||
| 2391 | zone_names[j], memmap_pages); | ||
| 2392 | } else | ||
| 2393 | printk(KERN_WARNING | ||
| 2394 | " %s zone: %lu pages exceeds realsize %lu\n", | ||
| 2395 | zone_names[j], memmap_pages, realsize); | ||
| 2396 | |||
| 2397 | /* Account for reserved DMA pages */ | ||
| 2398 | if (j == ZONE_DMA && realsize > dma_reserve) { | ||
| 2399 | realsize -= dma_reserve; | ||
| 2400 | printk(KERN_DEBUG " DMA zone: %lu pages reserved\n", | ||
| 2401 | dma_reserve); | ||
| 2402 | } | ||
| 2006 | 2403 | ||
| 2007 | if (!is_highmem_idx(j)) | 2404 | if (!is_highmem_idx(j)) |
| 2008 | nr_kernel_pages += realsize; | 2405 | nr_kernel_pages += realsize; |
| @@ -2011,6 +2408,7 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat, | |||
| 2011 | zone->spanned_pages = size; | 2408 | zone->spanned_pages = size; |
| 2012 | zone->present_pages = realsize; | 2409 | zone->present_pages = realsize; |
| 2013 | #ifdef CONFIG_NUMA | 2410 | #ifdef CONFIG_NUMA |
| 2411 | zone->node = nid; | ||
| 2014 | zone->min_unmapped_pages = (realsize*sysctl_min_unmapped_ratio) | 2412 | zone->min_unmapped_pages = (realsize*sysctl_min_unmapped_ratio) |
| 2015 | / 100; | 2413 | / 100; |
| 2016 | zone->min_slab_pages = (realsize * sysctl_min_slab_ratio) / 100; | 2414 | zone->min_slab_pages = (realsize * sysctl_min_slab_ratio) / 100; |
| @@ -2073,8 +2471,13 @@ static void __init alloc_node_mem_map(struct pglist_data *pgdat) | |||
| 2073 | /* | 2471 | /* |
| 2074 | * With no DISCONTIG, the global mem_map is just set as node 0's | 2472 | * With no DISCONTIG, the global mem_map is just set as node 0's |
| 2075 | */ | 2473 | */ |
| 2076 | if (pgdat == NODE_DATA(0)) | 2474 | if (pgdat == NODE_DATA(0)) { |
| 2077 | mem_map = NODE_DATA(0)->node_mem_map; | 2475 | mem_map = NODE_DATA(0)->node_mem_map; |
| 2476 | #ifdef CONFIG_ARCH_POPULATES_NODE_MAP | ||
| 2477 | if (page_to_pfn(mem_map) != pgdat->node_start_pfn) | ||
| 2478 | mem_map -= pgdat->node_start_pfn; | ||
| 2479 | #endif /* CONFIG_ARCH_POPULATES_NODE_MAP */ | ||
| 2480 | } | ||
| 2078 | #endif | 2481 | #endif |
| 2079 | #endif /* CONFIG_FLAT_NODE_MEM_MAP */ | 2482 | #endif /* CONFIG_FLAT_NODE_MEM_MAP */ |
| 2080 | } | 2483 | } |
| @@ -2085,13 +2488,255 @@ void __meminit free_area_init_node(int nid, struct pglist_data *pgdat, | |||
| 2085 | { | 2488 | { |
| 2086 | pgdat->node_id = nid; | 2489 | pgdat->node_id = nid; |
| 2087 | pgdat->node_start_pfn = node_start_pfn; | 2490 | pgdat->node_start_pfn = node_start_pfn; |
| 2088 | calculate_zone_totalpages(pgdat, zones_size, zholes_size); | 2491 | calculate_node_totalpages(pgdat, zones_size, zholes_size); |
| 2089 | 2492 | ||
| 2090 | alloc_node_mem_map(pgdat); | 2493 | alloc_node_mem_map(pgdat); |
| 2091 | 2494 | ||
| 2092 | free_area_init_core(pgdat, zones_size, zholes_size); | 2495 | free_area_init_core(pgdat, zones_size, zholes_size); |
| 2093 | } | 2496 | } |
| 2094 | 2497 | ||
| 2498 | #ifdef CONFIG_ARCH_POPULATES_NODE_MAP | ||
| 2499 | /** | ||
| 2500 | * add_active_range - Register a range of PFNs backed by physical memory | ||
| 2501 | * @nid: The node ID the range resides on | ||
| 2502 | * @start_pfn: The start PFN of the available physical memory | ||
| 2503 | * @end_pfn: The end PFN of the available physical memory | ||
| 2504 | * | ||
| 2505 | * These ranges are stored in an early_node_map[] and later used by | ||
| 2506 | * free_area_init_nodes() to calculate zone sizes and holes. If the | ||
| 2507 | * range spans a memory hole, it is up to the architecture to ensure | ||
| 2508 | * the memory is not freed by the bootmem allocator. If possible | ||
| 2509 | * the range being registered will be merged with existing ranges. | ||
| 2510 | */ | ||
| 2511 | void __init add_active_range(unsigned int nid, unsigned long start_pfn, | ||
| 2512 | unsigned long end_pfn) | ||
| 2513 | { | ||
| 2514 | int i; | ||
| 2515 | |||
| 2516 | printk(KERN_DEBUG "Entering add_active_range(%d, %lu, %lu) " | ||
| 2517 | "%d entries of %d used\n", | ||
| 2518 | nid, start_pfn, end_pfn, | ||
| 2519 | nr_nodemap_entries, MAX_ACTIVE_REGIONS); | ||
| 2520 | |||
| 2521 | /* Merge with existing active regions if possible */ | ||
| 2522 | for (i = 0; i < nr_nodemap_entries; i++) { | ||
| 2523 | if (early_node_map[i].nid != nid) | ||
| 2524 | continue; | ||
| 2525 | |||
| 2526 | /* Skip if an existing region covers this new one */ | ||
| 2527 | if (start_pfn >= early_node_map[i].start_pfn && | ||
| 2528 | end_pfn <= early_node_map[i].end_pfn) | ||
| 2529 | return; | ||
| 2530 | |||
| 2531 | /* Merge forward if suitable */ | ||
| 2532 | if (start_pfn <= early_node_map[i].end_pfn && | ||
| 2533 | end_pfn > early_node_map[i].end_pfn) { | ||
| 2534 | early_node_map[i].end_pfn = end_pfn; | ||
| 2535 | return; | ||
| 2536 | } | ||
| 2537 | |||
| 2538 | /* Merge backward if suitable */ | ||
| 2539 | if (start_pfn < early_node_map[i].end_pfn && | ||
| 2540 | end_pfn >= early_node_map[i].start_pfn) { | ||
| 2541 | early_node_map[i].start_pfn = start_pfn; | ||
| 2542 | return; | ||
| 2543 | } | ||
| 2544 | } | ||
| 2545 | |||
| 2546 | /* Check that early_node_map is large enough */ | ||
| 2547 | if (i >= MAX_ACTIVE_REGIONS) { | ||
| 2548 | printk(KERN_CRIT "More than %d memory regions, truncating\n", | ||
| 2549 | MAX_ACTIVE_REGIONS); | ||
| 2550 | return; | ||
| 2551 | } | ||
| 2552 | |||
| 2553 | early_node_map[i].nid = nid; | ||
| 2554 | early_node_map[i].start_pfn = start_pfn; | ||
| 2555 | early_node_map[i].end_pfn = end_pfn; | ||
| 2556 | nr_nodemap_entries = i + 1; | ||
| 2557 | } | ||
| 2558 | |||
| 2559 | /** | ||
| 2560 | * shrink_active_range - Shrink an existing registered range of PFNs | ||
| 2561 | * @nid: The node id the range is on that should be shrunk | ||
| 2562 | * @old_end_pfn: The old end PFN of the range | ||
| 2563 | * @new_end_pfn: The new PFN of the range | ||
| 2564 | * | ||
| 2565 | * i386 with NUMA use alloc_remap() to store a node_mem_map on a local node. | ||
| 2566 | * The map is kept at the end physical page range that has already been | ||
| 2567 | * registered with add_active_range(). This function allows an arch to shrink | ||
| 2568 | * an existing registered range. | ||
| 2569 | */ | ||
| 2570 | void __init shrink_active_range(unsigned int nid, unsigned long old_end_pfn, | ||
| 2571 | unsigned long new_end_pfn) | ||
| 2572 | { | ||
| 2573 | int i; | ||
| 2574 | |||
| 2575 | /* Find the old active region end and shrink */ | ||
| 2576 | for_each_active_range_index_in_nid(i, nid) | ||
| 2577 | if (early_node_map[i].end_pfn == old_end_pfn) { | ||
| 2578 | early_node_map[i].end_pfn = new_end_pfn; | ||
| 2579 | break; | ||
| 2580 | } | ||
| 2581 | } | ||
| 2582 | |||
| 2583 | /** | ||
| 2584 | * remove_all_active_ranges - Remove all currently registered regions | ||
| 2585 | * During discovery, it may be found that a table like SRAT is invalid | ||
| 2586 | * and an alternative discovery method must be used. This function removes | ||
| 2587 | * all currently registered regions. | ||
| 2588 | */ | ||
| 2589 | void __init remove_all_active_ranges() | ||
| 2590 | { | ||
| 2591 | memset(early_node_map, 0, sizeof(early_node_map)); | ||
| 2592 | nr_nodemap_entries = 0; | ||
| 2593 | #ifdef CONFIG_MEMORY_HOTPLUG_RESERVE | ||
| 2594 | memset(node_boundary_start_pfn, 0, sizeof(node_boundary_start_pfn)); | ||
| 2595 | memset(node_boundary_end_pfn, 0, sizeof(node_boundary_end_pfn)); | ||
| 2596 | #endif /* CONFIG_MEMORY_HOTPLUG_RESERVE */ | ||
| 2597 | } | ||
| 2598 | |||
| 2599 | /* Compare two active node_active_regions */ | ||
| 2600 | static int __init cmp_node_active_region(const void *a, const void *b) | ||
| 2601 | { | ||
| 2602 | struct node_active_region *arange = (struct node_active_region *)a; | ||
| 2603 | struct node_active_region *brange = (struct node_active_region *)b; | ||
| 2604 | |||
| 2605 | /* Done this way to avoid overflows */ | ||
| 2606 | if (arange->start_pfn > brange->start_pfn) | ||
| 2607 | return 1; | ||
| 2608 | if (arange->start_pfn < brange->start_pfn) | ||
| 2609 | return -1; | ||
| 2610 | |||
| 2611 | return 0; | ||
| 2612 | } | ||
| 2613 | |||
| 2614 | /* sort the node_map by start_pfn */ | ||
| 2615 | static void __init sort_node_map(void) | ||
| 2616 | { | ||
| 2617 | sort(early_node_map, (size_t)nr_nodemap_entries, | ||
| 2618 | sizeof(struct node_active_region), | ||
| 2619 | cmp_node_active_region, NULL); | ||
| 2620 | } | ||
| 2621 | |||
| 2622 | /* Find the lowest pfn for a node. This depends on a sorted early_node_map */ | ||
| 2623 | unsigned long __init find_min_pfn_for_node(unsigned long nid) | ||
| 2624 | { | ||
| 2625 | int i; | ||
| 2626 | |||
| 2627 | /* Assuming a sorted map, the first range found has the starting pfn */ | ||
| 2628 | for_each_active_range_index_in_nid(i, nid) | ||
| 2629 | return early_node_map[i].start_pfn; | ||
| 2630 | |||
| 2631 | printk(KERN_WARNING "Could not find start_pfn for node %lu\n", nid); | ||
| 2632 | return 0; | ||
| 2633 | } | ||
| 2634 | |||
| 2635 | /** | ||
| 2636 | * find_min_pfn_with_active_regions - Find the minimum PFN registered | ||
| 2637 | * | ||
| 2638 | * It returns the minimum PFN based on information provided via | ||
| 2639 | * add_active_range() | ||
| 2640 | */ | ||
| 2641 | unsigned long __init find_min_pfn_with_active_regions(void) | ||
| 2642 | { | ||
| 2643 | return find_min_pfn_for_node(MAX_NUMNODES); | ||
| 2644 | } | ||
| 2645 | |||
| 2646 | /** | ||
| 2647 | * find_max_pfn_with_active_regions - Find the maximum PFN registered | ||
| 2648 | * | ||
| 2649 | * It returns the maximum PFN based on information provided via | ||
| 2650 | * add_active_range() | ||
| 2651 | */ | ||
| 2652 | unsigned long __init find_max_pfn_with_active_regions(void) | ||
| 2653 | { | ||
| 2654 | int i; | ||
| 2655 | unsigned long max_pfn = 0; | ||
| 2656 | |||
| 2657 | for (i = 0; i < nr_nodemap_entries; i++) | ||
| 2658 | max_pfn = max(max_pfn, early_node_map[i].end_pfn); | ||
| 2659 | |||
| 2660 | return max_pfn; | ||
| 2661 | } | ||
| 2662 | |||
| 2663 | /** | ||
| 2664 | * free_area_init_nodes - Initialise all pg_data_t and zone data | ||
| 2665 | * @arch_max_dma_pfn: The maximum PFN usable for ZONE_DMA | ||
| 2666 | * @arch_max_dma32_pfn: The maximum PFN usable for ZONE_DMA32 | ||
| 2667 | * @arch_max_low_pfn: The maximum PFN usable for ZONE_NORMAL | ||
| 2668 | * @arch_max_high_pfn: The maximum PFN usable for ZONE_HIGHMEM | ||
| 2669 | * | ||
| 2670 | * This will call free_area_init_node() for each active node in the system. | ||
| 2671 | * Using the page ranges provided by add_active_range(), the size of each | ||
| 2672 | * zone in each node and their holes is calculated. If the maximum PFN | ||
| 2673 | * between two adjacent zones match, it is assumed that the zone is empty. | ||
| 2674 | * For example, if arch_max_dma_pfn == arch_max_dma32_pfn, it is assumed | ||
| 2675 | * that arch_max_dma32_pfn has no pages. It is also assumed that a zone | ||
| 2676 | * starts where the previous one ended. For example, ZONE_DMA32 starts | ||
| 2677 | * at arch_max_dma_pfn. | ||
| 2678 | */ | ||
| 2679 | void __init free_area_init_nodes(unsigned long *max_zone_pfn) | ||
| 2680 | { | ||
| 2681 | unsigned long nid; | ||
| 2682 | enum zone_type i; | ||
| 2683 | |||
| 2684 | /* Record where the zone boundaries are */ | ||
| 2685 | memset(arch_zone_lowest_possible_pfn, 0, | ||
| 2686 | sizeof(arch_zone_lowest_possible_pfn)); | ||
| 2687 | memset(arch_zone_highest_possible_pfn, 0, | ||
| 2688 | sizeof(arch_zone_highest_possible_pfn)); | ||
| 2689 | arch_zone_lowest_possible_pfn[0] = find_min_pfn_with_active_regions(); | ||
| 2690 | arch_zone_highest_possible_pfn[0] = max_zone_pfn[0]; | ||
| 2691 | for (i = 1; i < MAX_NR_ZONES; i++) { | ||
| 2692 | arch_zone_lowest_possible_pfn[i] = | ||
| 2693 | arch_zone_highest_possible_pfn[i-1]; | ||
| 2694 | arch_zone_highest_possible_pfn[i] = | ||
| 2695 | max(max_zone_pfn[i], arch_zone_lowest_possible_pfn[i]); | ||
| 2696 | } | ||
| 2697 | |||
| 2698 | /* Regions in the early_node_map can be in any order */ | ||
| 2699 | sort_node_map(); | ||
| 2700 | |||
| 2701 | /* Print out the zone ranges */ | ||
| 2702 | printk("Zone PFN ranges:\n"); | ||
| 2703 | for (i = 0; i < MAX_NR_ZONES; i++) | ||
| 2704 | printk(" %-8s %8lu -> %8lu\n", | ||
| 2705 | zone_names[i], | ||
| 2706 | arch_zone_lowest_possible_pfn[i], | ||
| 2707 | arch_zone_highest_possible_pfn[i]); | ||
| 2708 | |||
| 2709 | /* Print out the early_node_map[] */ | ||
| 2710 | printk("early_node_map[%d] active PFN ranges\n", nr_nodemap_entries); | ||
| 2711 | for (i = 0; i < nr_nodemap_entries; i++) | ||
| 2712 | printk(" %3d: %8lu -> %8lu\n", early_node_map[i].nid, | ||
| 2713 | early_node_map[i].start_pfn, | ||
| 2714 | early_node_map[i].end_pfn); | ||
| 2715 | |||
| 2716 | /* Initialise every node */ | ||
| 2717 | for_each_online_node(nid) { | ||
| 2718 | pg_data_t *pgdat = NODE_DATA(nid); | ||
| 2719 | free_area_init_node(nid, pgdat, NULL, | ||
| 2720 | find_min_pfn_for_node(nid), NULL); | ||
| 2721 | } | ||
| 2722 | } | ||
| 2723 | #endif /* CONFIG_ARCH_POPULATES_NODE_MAP */ | ||
| 2724 | |||
| 2725 | /** | ||
| 2726 | * set_dma_reserve - Account the specified number of pages reserved in ZONE_DMA | ||
| 2727 | * @new_dma_reserve - The number of pages to mark reserved | ||
| 2728 | * | ||
| 2729 | * The per-cpu batchsize and zone watermarks are determined by present_pages. | ||
| 2730 | * In the DMA zone, a significant percentage may be consumed by kernel image | ||
| 2731 | * and other unfreeable allocations which can skew the watermarks badly. This | ||
| 2732 | * function may optionally be used to account for unfreeable pages in | ||
| 2733 | * ZONE_DMA. The effect will be lower watermarks and smaller per-cpu batchsize | ||
| 2734 | */ | ||
| 2735 | void __init set_dma_reserve(unsigned long new_dma_reserve) | ||
| 2736 | { | ||
| 2737 | dma_reserve = new_dma_reserve; | ||
| 2738 | } | ||
| 2739 | |||
| 2095 | #ifndef CONFIG_NEED_MULTIPLE_NODES | 2740 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
| 2096 | static bootmem_data_t contig_bootmem_data; | 2741 | static bootmem_data_t contig_bootmem_data; |
| 2097 | struct pglist_data contig_page_data = { .bdata = &contig_bootmem_data }; | 2742 | struct pglist_data contig_page_data = { .bdata = &contig_bootmem_data }; |
