/* 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); }
void __init build_cnode_tables(void) { int nasid; int node; lboard_t *brd; memset(physical_node_map, -1, sizeof(physical_node_map)); memset(sn_cnodeid_to_nasid, -1, sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid))); /* * First populate the tables with C/M bricks. This ensures that * cnode == node for all C & M bricks. */ for_each_online_node(node) { nasid = pxm_to_nasid(node_to_pxm(node)); sn_cnodeid_to_nasid[node] = nasid; physical_node_map[nasid] = node; } /* * num_cnodes is total number of C/M/TIO bricks. Because of the 256 node * limit on the number of nodes, we can't use the generic node numbers * for this. Note that num_cnodes is incremented below as TIOs or * headless/memoryless nodes are discovered. */ num_cnodes = num_online_nodes(); /* fakeprom does not support klgraph */ if (IS_RUNNING_ON_FAKE_PROM()) return; /* Find TIOs & headless/memoryless nodes and add them to the tables */ for_each_online_node(node) { kl_config_hdr_t *klgraph_header; nasid = cnodeid_to_nasid(node); klgraph_header = ia64_sn_get_klconfig_addr(nasid); if (klgraph_header == NULL) BUG(); brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info); while (brd) { if (board_needs_cnode(brd->brd_type) && physical_node_map[brd->brd_nasid] < 0) { sn_cnodeid_to_nasid[num_cnodes] = brd->brd_nasid; physical_node_map[brd->brd_nasid] = num_cnodes++; } brd = find_lboard_next(brd); } } }
/* 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); } }
/* 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_memblks(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, start, end); if (ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) { update_nodes_add(node, start, end); /* restore nodes[node] */ *nd = oldnode; if ((nd->start | nd->end) == 0) node_clear(node, nodes_parsed); } node_memblk_range[num_node_memblks].start = start; node_memblk_range[num_node_memblks].end = end; memblk_nodeid[num_node_memblks] = node; num_node_memblks++; }