X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fi386%2Fkernel%2Fsrat.c;h=52b3ed5d2cb53c88bb6a48659ac91901bc872d41;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=8c0bd561f4d6ce0b6ed8aec574bfe9ce0e5faef5;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c index 8c0bd561f..52b3ed5d2 100644 --- a/arch/i386/kernel/srat.c +++ b/arch/i386/kernel/srat.c @@ -28,7 +28,9 @@ #include #include #include +#include #include +#include /* * proximity macros and definitions @@ -57,8 +59,6 @@ static int num_memory_chunks; /* total number of memory chunks */ static int zholes_size_init; static unsigned long zholes_size[MAX_NUMNODES * MAX_NR_ZONES]; -extern unsigned long node_start_pfn[], node_end_pfn[]; - extern void * boot_ioremap(unsigned long, unsigned long); /* Identify CPU proximity domains */ @@ -137,8 +137,8 @@ static void __init parse_memory_affinity_structure (char *sratp) "enabled and removable" : "enabled" ) ); } -#if MAX_NR_ZONES != 3 -#error "MAX_NR_ZONES != 3, chunk_to_zone requires review" +#if MAX_NR_ZONES != 4 +#error "MAX_NR_ZONES != 4, chunk_to_zone requires review" #endif /* Take a chunk of pages from page frame cstart to cend and count the number * of pages in each zone, returned via zones[]. @@ -181,21 +181,43 @@ static __init void chunk_to_zones(unsigned long cstart, unsigned long cend, } } -static void __init initialize_physnode_map(void) +/* + * The SRAT table always lists ascending addresses, so can always + * assume that the first "start" address that you see is the real + * start of the node, and that the current "end" address is after + * the previous one. + */ +static __init void node_read_chunk(int nid, struct node_memory_chunk_s *memory_chunk) { - int i; - unsigned long pfn; - struct node_memory_chunk_s *nmcp; - - /* Run the list of memory chunks and fill in the phymap. */ - nmcp = node_memory_chunk; - for (i = num_memory_chunks; --i >= 0; nmcp++) { - for (pfn = nmcp->start_pfn; pfn <= nmcp->end_pfn; - pfn += PAGES_PER_ELEMENT) - { - physnode_map[pfn / PAGES_PER_ELEMENT] = (int)nmcp->nid; - } + /* + * Only add present memory as told by the e820. + * There is no guarantee from the SRAT that the memory it + * enumerates is present at boot time because it represents + * *possible* memory hotplug areas the same as normal RAM. + */ + if (memory_chunk->start_pfn >= max_pfn) { + printk (KERN_INFO "Ignoring SRAT pfns: 0x%08lx -> %08lx\n", + memory_chunk->start_pfn, memory_chunk->end_pfn); + return; } + if (memory_chunk->nid != nid) + return; + + if (!node_has_online_mem(nid)) + node_start_pfn[nid] = memory_chunk->start_pfn; + + if (node_start_pfn[nid] > memory_chunk->start_pfn) + node_start_pfn[nid] = memory_chunk->start_pfn; + + if (node_end_pfn[nid] < memory_chunk->end_pfn) + node_end_pfn[nid] = memory_chunk->end_pfn; +} + +static u8 pxm_to_nid_map[MAX_PXM_DOMAINS];/* _PXM to logical node ID map */ + +int pxm_to_node(int pxm) +{ + return pxm_to_nid_map[pxm]; } /* Parse the ACPI Static Resource Affinity Table */ @@ -203,7 +225,6 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) { u8 *start, *end, *p; int i, j, nid; - u8 pxm_to_nid_map[MAX_PXM_DOMAINS];/* _PXM to logical node ID map */ u8 nid_to_pxm_map[MAX_NUMNODES];/* logical node ID to _PXM map */ start = (u8 *)(&(sratp->reserved) + 1); /* skip header */ @@ -248,57 +269,48 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) * a set of sequential node IDs starting at zero. (ACPI doesn't seem * to specify the range of _PXM values.) */ - numnodes = 0; /* init total nodes in system */ + /* + * MCD - we no longer HAVE to number nodes sequentially. PXM domain + * numbers could go as high as 256, and MAX_NUMNODES for i386 is typically + * 32, so we will continue numbering them in this manner until MAX_NUMNODES + * approaches MAX_PXM_DOMAINS for i386. + */ + nodes_clear(node_online_map); for (i = 0; i < MAX_PXM_DOMAINS; i++) { if (BMAP_TEST(pxm_bitmap, i)) { - pxm_to_nid_map[i] = numnodes; - nid_to_pxm_map[numnodes] = i; - node_set_online(numnodes); - ++numnodes; + nid = num_online_nodes(); + pxm_to_nid_map[i] = nid; + nid_to_pxm_map[nid] = i; + node_set_online(nid); } } - - if (numnodes == 0) - BUG(); + BUG_ON(num_online_nodes() == 0); /* set cnode id in memory chunk structure */ for (i = 0; i < num_memory_chunks; i++) node_memory_chunk[i].nid = pxm_to_nid_map[node_memory_chunk[i].pxm]; - initialize_physnode_map(); - printk("pxm bitmap: "); for (i = 0; i < sizeof(pxm_bitmap); i++) { printk("%02X ", pxm_bitmap[i]); } printk("\n"); - printk("Number of logical nodes in system = %d\n", numnodes); + printk("Number of logical nodes in system = %d\n", num_online_nodes()); printk("Number of memory chunks in system = %d\n", num_memory_chunks); for (j = 0; j < num_memory_chunks; j++){ + struct node_memory_chunk_s * chunk = &node_memory_chunk[j]; printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n", - j, node_memory_chunk[j].nid, - node_memory_chunk[j].start_pfn, - node_memory_chunk[j].end_pfn); + j, chunk->nid, chunk->start_pfn, chunk->end_pfn); + node_read_chunk(chunk->nid, chunk); } - /*calculate node_start_pfn/node_end_pfn arrays*/ - for (nid = 0; nid < numnodes; nid++) { - int been_here_before = 0; - - for (j = 0; j < num_memory_chunks; j++){ - if (node_memory_chunk[j].nid == nid) { - if (been_here_before == 0) { - node_start_pfn[nid] = node_memory_chunk[j].start_pfn; - node_end_pfn[nid] = node_memory_chunk[j].end_pfn; - been_here_before = 1; - } else { /* We've found another chunk of memory for the node */ - if (node_start_pfn[nid] < node_memory_chunk[j].start_pfn) { - node_end_pfn[nid] = node_memory_chunk[j].end_pfn; - } - } - } - } + for_each_online_node(nid) { + unsigned long start = node_start_pfn[nid]; + unsigned long end = node_end_pfn[nid]; + + memory_present(nid, start, end); + node_remap_size[nid] = node_memmap_size_bytes(nid, start, end); } return 1; out_fail: @@ -315,7 +327,12 @@ int __init get_memcfg_from_srat(void) int tables = 0; int i = 0; - acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING, rsdp_address); + if (ACPI_FAILURE(acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING, + rsdp_address))) { + printk("%s: System description tables not found\n", + __FUNCTION__); + goto out_err; + } if (rsdp_address->pointer_type == ACPI_PHYSICAL_POINTER) { printk("%s: assigning address to rsdp\n", __FUNCTION__); @@ -415,7 +432,7 @@ static void __init get_zholes_init(void) int first; unsigned long end = 0; - for (nid = 0; nid < numnodes; nid++) { + for_each_online_node(nid) { first = 1; for (c = 0; c < num_memory_chunks; c++){ if (node_memory_chunk[c].nid == nid) { @@ -443,8 +460,8 @@ unsigned long * __init get_zholes_size(int nid) zholes_size_init++; get_zholes_init(); } - if((nid >= numnodes) | (nid >= MAX_NUMNODES)) - printk("%s: nid = %d is invalid. numnodes = %d", - __FUNCTION__, nid, numnodes); + if (nid >= MAX_NUMNODES || !node_online(nid)) + printk("%s: nid = %d is invalid/offline. num_online_nodes = %d", + __FUNCTION__, nid, num_online_nodes()); return &zholes_size[nid * MAX_NR_ZONES]; }