|
@@ -39,96 +39,6 @@ static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES];
|
|
|
static int min_common_depth;
|
|
|
static int n_mem_addr_cells, n_mem_size_cells;
|
|
|
|
|
|
-/*
|
|
|
- * We need somewhere to store start/end/node for each region until we have
|
|
|
- * allocated the real node_data structures.
|
|
|
- */
|
|
|
-#define MAX_REGIONS (MAX_LMB_REGIONS*2)
|
|
|
-static struct {
|
|
|
- unsigned long start_pfn;
|
|
|
- unsigned long end_pfn;
|
|
|
- int nid;
|
|
|
-} init_node_data[MAX_REGIONS] __initdata;
|
|
|
-
|
|
|
-int __init early_pfn_to_nid(unsigned long pfn)
|
|
|
-{
|
|
|
- unsigned int i;
|
|
|
-
|
|
|
- for (i = 0; init_node_data[i].end_pfn; i++) {
|
|
|
- unsigned long start_pfn = init_node_data[i].start_pfn;
|
|
|
- unsigned long end_pfn = init_node_data[i].end_pfn;
|
|
|
-
|
|
|
- if ((start_pfn <= pfn) && (pfn < end_pfn))
|
|
|
- return init_node_data[i].nid;
|
|
|
- }
|
|
|
-
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-void __init add_region(unsigned int nid, unsigned long start_pfn,
|
|
|
- unsigned long pages)
|
|
|
-{
|
|
|
- unsigned int i;
|
|
|
-
|
|
|
- dbg("add_region nid %d start_pfn 0x%lx pages 0x%lx\n",
|
|
|
- nid, start_pfn, pages);
|
|
|
-
|
|
|
- for (i = 0; init_node_data[i].end_pfn; i++) {
|
|
|
- if (init_node_data[i].nid != nid)
|
|
|
- continue;
|
|
|
- if (init_node_data[i].end_pfn == start_pfn) {
|
|
|
- init_node_data[i].end_pfn += pages;
|
|
|
- return;
|
|
|
- }
|
|
|
- if (init_node_data[i].start_pfn == (start_pfn + pages)) {
|
|
|
- init_node_data[i].start_pfn -= pages;
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Leave last entry NULL so we dont iterate off the end (we use
|
|
|
- * entry.end_pfn to terminate the walk).
|
|
|
- */
|
|
|
- if (i >= (MAX_REGIONS - 1)) {
|
|
|
- printk(KERN_ERR "WARNING: too many memory regions in "
|
|
|
- "numa code, truncating\n");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- init_node_data[i].start_pfn = start_pfn;
|
|
|
- init_node_data[i].end_pfn = start_pfn + pages;
|
|
|
- init_node_data[i].nid = nid;
|
|
|
-}
|
|
|
-
|
|
|
-/* We assume init_node_data has no overlapping regions */
|
|
|
-void __init get_region(unsigned int nid, unsigned long *start_pfn,
|
|
|
- unsigned long *end_pfn, unsigned long *pages_present)
|
|
|
-{
|
|
|
- unsigned int i;
|
|
|
-
|
|
|
- *start_pfn = -1UL;
|
|
|
- *end_pfn = *pages_present = 0;
|
|
|
-
|
|
|
- for (i = 0; init_node_data[i].end_pfn; i++) {
|
|
|
- if (init_node_data[i].nid != nid)
|
|
|
- continue;
|
|
|
-
|
|
|
- *pages_present += init_node_data[i].end_pfn -
|
|
|
- init_node_data[i].start_pfn;
|
|
|
-
|
|
|
- if (init_node_data[i].start_pfn < *start_pfn)
|
|
|
- *start_pfn = init_node_data[i].start_pfn;
|
|
|
-
|
|
|
- if (init_node_data[i].end_pfn > *end_pfn)
|
|
|
- *end_pfn = init_node_data[i].end_pfn;
|
|
|
- }
|
|
|
-
|
|
|
- /* We didnt find a matching region, return start/end as 0 */
|
|
|
- if (*start_pfn == -1UL)
|
|
|
- *start_pfn = 0;
|
|
|
-}
|
|
|
-
|
|
|
static void __cpuinit map_cpu_to_node(int cpu, int node)
|
|
|
{
|
|
|
numa_cpu_lookup_table[cpu] = node;
|
|
@@ -468,8 +378,8 @@ new_range:
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- add_region(nid, start >> PAGE_SHIFT,
|
|
|
- size >> PAGE_SHIFT);
|
|
|
+ add_active_range(nid, start >> PAGE_SHIFT,
|
|
|
+ (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT));
|
|
|
|
|
|
if (--ranges)
|
|
|
goto new_range;
|
|
@@ -482,6 +392,7 @@ static void __init setup_nonnuma(void)
|
|
|
{
|
|
|
unsigned long top_of_ram = lmb_end_of_DRAM();
|
|
|
unsigned long total_ram = lmb_phys_mem_size();
|
|
|
+ unsigned long start_pfn, end_pfn;
|
|
|
unsigned int i;
|
|
|
|
|
|
printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
|
|
@@ -489,9 +400,11 @@ static void __init setup_nonnuma(void)
|
|
|
printk(KERN_DEBUG "Memory hole size: %ldMB\n",
|
|
|
(top_of_ram - total_ram) >> 20);
|
|
|
|
|
|
- for (i = 0; i < lmb.memory.cnt; ++i)
|
|
|
- add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT,
|
|
|
- lmb_size_pages(&lmb.memory, i));
|
|
|
+ for (i = 0; i < lmb.memory.cnt; ++i) {
|
|
|
+ start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
|
|
|
+ end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
|
|
|
+ add_active_range(0, start_pfn, end_pfn);
|
|
|
+ }
|
|
|
node_set_online(0);
|
|
|
}
|
|
|
|
|
@@ -630,11 +543,11 @@ void __init do_init_bootmem(void)
|
|
|
(void *)(unsigned long)boot_cpuid);
|
|
|
|
|
|
for_each_online_node(nid) {
|
|
|
- unsigned long start_pfn, end_pfn, pages_present;
|
|
|
+ unsigned long start_pfn, end_pfn;
|
|
|
unsigned long bootmem_paddr;
|
|
|
unsigned long bootmap_pages;
|
|
|
|
|
|
- get_region(nid, &start_pfn, &end_pfn, &pages_present);
|
|
|
+ get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
|
|
|
|
|
|
/* Allocate the node structure node local if possible */
|
|
|
NODE_DATA(nid) = careful_allocation(nid,
|
|
@@ -667,19 +580,7 @@ void __init do_init_bootmem(void)
|
|
|
init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
|
|
|
start_pfn, end_pfn);
|
|
|
|
|
|
- /* Add free regions on this node */
|
|
|
- for (i = 0; init_node_data[i].end_pfn; i++) {
|
|
|
- unsigned long start, end;
|
|
|
-
|
|
|
- if (init_node_data[i].nid != nid)
|
|
|
- continue;
|
|
|
-
|
|
|
- start = init_node_data[i].start_pfn << PAGE_SHIFT;
|
|
|
- end = init_node_data[i].end_pfn << PAGE_SHIFT;
|
|
|
-
|
|
|
- dbg("free_bootmem %lx %lx\n", start, end - start);
|
|
|
- free_bootmem_node(NODE_DATA(nid), start, end - start);
|
|
|
- }
|
|
|
+ free_bootmem_with_active_regions(nid, end_pfn);
|
|
|
|
|
|
/* Mark reserved regions on this node */
|
|
|
for (i = 0; i < lmb.reserved.cnt; i++) {
|
|
@@ -710,44 +611,16 @@ void __init do_init_bootmem(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /* Add regions into sparsemem */
|
|
|
- for (i = 0; init_node_data[i].end_pfn; i++) {
|
|
|
- unsigned long start, end;
|
|
|
-
|
|
|
- if (init_node_data[i].nid != nid)
|
|
|
- continue;
|
|
|
-
|
|
|
- start = init_node_data[i].start_pfn;
|
|
|
- end = init_node_data[i].end_pfn;
|
|
|
-
|
|
|
- memory_present(nid, start, end);
|
|
|
- }
|
|
|
+ sparse_memory_present_with_active_regions(nid);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void __init paging_init(void)
|
|
|
{
|
|
|
- unsigned long zones_size[MAX_NR_ZONES];
|
|
|
- unsigned long zholes_size[MAX_NR_ZONES];
|
|
|
- int nid;
|
|
|
-
|
|
|
- memset(zones_size, 0, sizeof(zones_size));
|
|
|
- memset(zholes_size, 0, sizeof(zholes_size));
|
|
|
-
|
|
|
- for_each_online_node(nid) {
|
|
|
- unsigned long start_pfn, end_pfn, pages_present;
|
|
|
-
|
|
|
- get_region(nid, &start_pfn, &end_pfn, &pages_present);
|
|
|
-
|
|
|
- zones_size[ZONE_DMA] = end_pfn - start_pfn;
|
|
|
- zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - pages_present;
|
|
|
-
|
|
|
- dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid,
|
|
|
- zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]);
|
|
|
-
|
|
|
- free_area_init_node(nid, NODE_DATA(nid), zones_size, start_pfn,
|
|
|
- zholes_size);
|
|
|
- }
|
|
|
+ unsigned long max_zone_pfns[MAX_NR_ZONES] = {
|
|
|
+ lmb_end_of_DRAM() >> PAGE_SHIFT
|
|
|
+ };
|
|
|
+ free_area_init_nodes(max_zone_pfns);
|
|
|
}
|
|
|
|
|
|
static int __init early_numa(char *p)
|