/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ void __init acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) { struct node *nd; unsigned long start, end; int node, pxm; int i; if (srat_disabled() || ma->flags.enabled == 0) return; pxm = ma->proximity_domain; node = setup_node(pxm); if (node < 0) { printk(KERN_ERR "SRAT: Too many proximity domains.\n"); bad_srat(); return; } start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); /* It is fine to add this area to the nodes data it will be used later*/ if (ma->flags.hot_pluggable == 1) printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n", start, end); i = conflicting_nodes(start, end); if (i == node) { printk(KERN_WARNING "SRAT: Warning: PXM %d (%lx-%lx) overlaps with itself (%Lx-%Lx)\n", pxm, start, end, nodes[i].start, nodes[i].end); } else if (i >= 0) { printk(KERN_ERR "SRAT: PXM %d (%lx-%lx) overlaps with PXM %d (%Lx-%Lx)\n", pxm, start, end, node_to_pxm(i), nodes[i].start, nodes[i].end); bad_srat(); return; } nd = &nodes[node]; if (!node_test_and_set(node, nodes_parsed)) { nd->start = start; nd->end = end; } else { if (start < nd->start) nd->start = start; if (nd->end < end) nd->end = end; } if (!(nd->end & 0xfff)) nd->end--; printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, nd->start, nd->end); }
/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ void __init acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) { struct bootnode *nd, oldnode; unsigned long start, end; int node, pxm; int i; if (srat_disabled()) return; if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) { bad_srat(); return; } if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0) return; if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info()) return; start = ma->base_address; end = start + ma->length; pxm = ma->proximity_domain; node = setup_node(pxm); if (node < 0) { printk(KERN_ERR "SRAT: Too many proximity domains.\n"); bad_srat(); return; } i = conflicting_nodes(start, end); if (i == node) { printk(KERN_WARNING "SRAT: Warning: PXM %d (%lx-%lx) overlaps with itself (%Lx-%Lx)\n", pxm, start, end, nodes[i].start, nodes[i].end); } else if (i >= 0) { printk(KERN_ERR "SRAT: PXM %d (%lx-%lx) overlaps with PXM %d (%Lx-%Lx)\n", pxm, start, end, node_to_pxm(i), nodes[i].start, nodes[i].end); bad_srat(); return; } nd = &nodes[node]; oldnode = *nd; if (!node_test_and_set(node, nodes_parsed)) { nd->start = start; nd->end = end; } else { if (start < nd->start) nd->start = start; if (nd->end < end) nd->end = end; } printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, nd->start, nd->end); e820_register_active_regions(node, nd->start >> PAGE_SHIFT, nd->end >> PAGE_SHIFT); push_node_boundaries(node, nd->start >> PAGE_SHIFT, nd->end >> PAGE_SHIFT); if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && (reserve_hotadd(node, start, end) < 0)) { /* Ignore hotadd region. Undo damage */ printk(KERN_NOTICE "SRAT: Hotplug region ignored\n"); *nd = oldnode; if ((nd->start | nd->end) == 0) node_clear(node, nodes_parsed); } }