···5454extern unsigned long init_memory_mapping(unsigned long start,5555 unsigned long end);56565757-void init_memory_mapping_high(void);5858-5957extern void initmem_init(void);6058extern void free_initmem(void);6159
···606606void __init initmem_init(void)607607{608608 memblock_x86_register_active_regions(0, 0, max_pfn);609609- init_memory_mapping_high();610609}611610#endif612612-613613-struct mapping_work_data {614614- unsigned long start;615615- unsigned long end;616616- unsigned long pfn_mapped;617617-};618618-619619-static int __init_refok620620-mapping_work_fn(unsigned long start_pfn, unsigned long end_pfn, void *datax)621621-{622622- struct mapping_work_data *data = datax;623623- unsigned long pfn_mapped;624624- unsigned long final_start, final_end;625625-626626- final_start = max_t(unsigned long, start_pfn<<PAGE_SHIFT, data->start);627627- final_end = min_t(unsigned long, end_pfn<<PAGE_SHIFT, data->end);628628-629629- if (final_end <= final_start)630630- return 0;631631-632632- pfn_mapped = init_memory_mapping(final_start, final_end);633633-634634- if (pfn_mapped > data->pfn_mapped)635635- data->pfn_mapped = pfn_mapped;636636-637637- return 0;638638-}639639-640640-static unsigned long __init_refok641641-init_memory_mapping_active_regions(unsigned long start, unsigned long end)642642-{643643- struct mapping_work_data data;644644-645645- data.start = start;646646- data.end = end;647647- data.pfn_mapped = 0;648648-649649- work_with_active_regions(MAX_NUMNODES, mapping_work_fn, &data);650650-651651- return data.pfn_mapped;652652-}653653-654654-void __init_refok init_memory_mapping_high(void)655655-{656656- if (max_pfn > max_low_pfn) {657657- max_pfn_mapped = init_memory_mapping_active_regions(1UL<<32,658658- max_pfn<<PAGE_SHIFT);659659- /* can we preserve max_low_pfn ? */660660- max_low_pfn = max_pfn;661661-662662- memblock.current_limit = get_max_mapped();663663- }664664-}665611666612void __init paging_init(void)667613{
+57-43
arch/x86/mm/numa_64.c
···543543 if (!numa_meminfo_cover_memory(mi))544544 return -EINVAL;545545546546- init_memory_mapping_high();547547-548546 /* Finally register nodes. */549547 for_each_node_mask(nid, node_possible_map) {550548 u64 start = (u64)max_pfn << PAGE_SHIFT;···562564 return 0;563565}564566567567+/**568568+ * dummy_numma_init - Fallback dummy NUMA init569569+ *570570+ * Used if there's no underlying NUMA architecture, NUMA initialization571571+ * fails, or NUMA is disabled on the command line.572572+ *573573+ * Must online at least one node and add memory blocks that cover all574574+ * allowed memory. This function must not fail.575575+ */565576static int __init dummy_numa_init(void)566577{567578 printk(KERN_INFO "%s\n",···584577 return 0;585578}586579580580+static int __init numa_init(int (*init_func)(void))581581+{582582+ int i;583583+ int ret;584584+585585+ for (i = 0; i < MAX_LOCAL_APIC; i++)586586+ set_apicid_to_node(i, NUMA_NO_NODE);587587+588588+ nodes_clear(numa_nodes_parsed);589589+ nodes_clear(node_possible_map);590590+ nodes_clear(node_online_map);591591+ memset(&numa_meminfo, 0, sizeof(numa_meminfo));592592+ remove_all_active_ranges();593593+ numa_reset_distance();594594+595595+ ret = init_func();596596+ if (ret < 0)597597+ return ret;598598+ ret = numa_cleanup_meminfo(&numa_meminfo);599599+ if (ret < 0)600600+ return ret;601601+602602+ numa_emulation(&numa_meminfo, numa_distance_cnt);603603+604604+ ret = numa_register_memblks(&numa_meminfo);605605+ if (ret < 0)606606+ return ret;607607+608608+ for (i = 0; i < nr_cpu_ids; i++) {609609+ int nid = early_cpu_to_node(i);610610+611611+ if (nid == NUMA_NO_NODE)612612+ continue;613613+ if (!node_online(nid))614614+ numa_clear_node(i);615615+ }616616+ numa_init_array();617617+ return 0;618618+}619619+587620void __init initmem_init(void)588621{589589- int (*numa_init[])(void) = { [2] = dummy_numa_init };590590- int i, j;622622+ int ret;591623592624 if (!numa_off) {593625#ifdef CONFIG_ACPI_NUMA594594- numa_init[0] = x86_acpi_numa_init;626626+ ret = numa_init(x86_acpi_numa_init);627627+ if (!ret)628628+ return;595629#endif596630#ifdef CONFIG_AMD_NUMA597597- numa_init[1] = amd_numa_init;631631+ ret = numa_init(amd_numa_init);632632+ if (!ret)633633+ return;598634#endif599635 }600636601601- for (i = 0; i < ARRAY_SIZE(numa_init); i++) {602602- if (!numa_init[i])603603- continue;604604-605605- for (j = 0; j < MAX_LOCAL_APIC; j++)606606- set_apicid_to_node(j, NUMA_NO_NODE);607607-608608- nodes_clear(numa_nodes_parsed);609609- nodes_clear(node_possible_map);610610- nodes_clear(node_online_map);611611- memset(&numa_meminfo, 0, sizeof(numa_meminfo));612612- remove_all_active_ranges();613613- numa_reset_distance();614614-615615- if (numa_init[i]() < 0)616616- continue;617617-618618- if (numa_cleanup_meminfo(&numa_meminfo) < 0)619619- continue;620620-621621- numa_emulation(&numa_meminfo, numa_distance_cnt);622622-623623- if (numa_register_memblks(&numa_meminfo) < 0)624624- continue;625625-626626- for (j = 0; j < nr_cpu_ids; j++) {627627- int nid = early_cpu_to_node(j);628628-629629- if (nid == NUMA_NO_NODE)630630- continue;631631- if (!node_online(nid))632632- numa_clear_node(j);633633- }634634- numa_init_array();635635- return;636636- }637637- BUG();637637+ numa_init(dummy_numa_init);638638}639639640640unsigned long __init numa_free_all_bootmem(void)
+16-4
arch/x86/mm/numa_emulation.c
···301301 const u64 max_addr = max_pfn << PAGE_SHIFT;302302 u8 *phys_dist = NULL;303303 size_t phys_size = numa_dist_cnt * numa_dist_cnt * sizeof(phys_dist[0]);304304+ int dfl_phys_nid;304305 int i, j, ret;305306306307 if (!emu_cmdline)···358357 node_distance(i, j);359358 }360359360360+ /* determine the default phys nid to use for unmapped nodes */361361+ dfl_phys_nid = NUMA_NO_NODE;362362+ for (i = 0; i < ARRAY_SIZE(emu_nid_to_phys); i++) {363363+ if (emu_nid_to_phys[i] != NUMA_NO_NODE) {364364+ dfl_phys_nid = emu_nid_to_phys[i];365365+ break;366366+ }367367+ }368368+ if (dfl_phys_nid == NUMA_NO_NODE) {369369+ pr_warning("NUMA: Warning: can't determine default physical node, disabling emulation\n");370370+ goto no_emu;371371+ }372372+361373 /* commit */362374 *numa_meminfo = ei;363375···391377 /* make sure all emulated nodes are mapped to a physical node */392378 for (i = 0; i < ARRAY_SIZE(emu_nid_to_phys); i++)393379 if (emu_nid_to_phys[i] == NUMA_NO_NODE)394394- emu_nid_to_phys[i] = 0;380380+ emu_nid_to_phys[i] = dfl_phys_nid;395381396382 /*397383 * Transform distance table. numa_set_distance() ignores all···431417{432418 int physnid, nid;433419434434- nid = numa_cpu_node(cpu);435435- if (nid == NUMA_NO_NODE)436436- nid = early_cpu_to_node(cpu);420420+ nid = early_cpu_to_node(cpu);437421 BUG_ON(nid == NUMA_NO_NODE || !node_online(nid));438422439423 physnid = emu_nid_to_phys[nid];