aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/srat.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/srat.c')
-rw-r--r--arch/i386/kernel/srat.c102
1 files changed, 3 insertions, 99 deletions
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
index b1809c9a0899..32413122c4c2 100644
--- a/arch/i386/kernel/srat.c
+++ b/arch/i386/kernel/srat.c
@@ -42,7 +42,7 @@
42#define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8) 42#define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8)
43static u8 pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */ 43static u8 pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */
44 44
45#define MAX_CHUNKS_PER_NODE 4 45#define MAX_CHUNKS_PER_NODE 3
46#define MAXCHUNKS (MAX_CHUNKS_PER_NODE * MAX_NUMNODES) 46#define MAXCHUNKS (MAX_CHUNKS_PER_NODE * MAX_NUMNODES)
47struct node_memory_chunk_s { 47struct node_memory_chunk_s {
48 unsigned long start_pfn; 48 unsigned long start_pfn;
@@ -54,8 +54,6 @@ struct node_memory_chunk_s {
54static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS]; 54static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS];
55 55
56static int num_memory_chunks; /* total number of memory chunks */ 56static int num_memory_chunks; /* total number of memory chunks */
57static int zholes_size_init;
58static unsigned long zholes_size[MAX_NUMNODES * MAX_NR_ZONES];
59 57
60extern void * boot_ioremap(unsigned long, unsigned long); 58extern void * boot_ioremap(unsigned long, unsigned long);
61 59
@@ -135,50 +133,6 @@ static void __init parse_memory_affinity_structure (char *sratp)
135 "enabled and removable" : "enabled" ) ); 133 "enabled and removable" : "enabled" ) );
136} 134}
137 135
138#if MAX_NR_ZONES != 4
139#error "MAX_NR_ZONES != 4, chunk_to_zone requires review"
140#endif
141/* Take a chunk of pages from page frame cstart to cend and count the number
142 * of pages in each zone, returned via zones[].
143 */
144static __init void chunk_to_zones(unsigned long cstart, unsigned long cend,
145 unsigned long *zones)
146{
147 unsigned long max_dma;
148 extern unsigned long max_low_pfn;
149
150 int z;
151 unsigned long rend;
152
153 /* FIXME: MAX_DMA_ADDRESS and max_low_pfn are trying to provide
154 * similarly scoped information and should be handled in a consistant
155 * manner.
156 */
157 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
158
159 /* Split the hole into the zones in which it falls. Repeatedly
160 * take the segment in which the remaining hole starts, round it
161 * to the end of that zone.
162 */
163 memset(zones, 0, MAX_NR_ZONES * sizeof(long));
164 while (cstart < cend) {
165 if (cstart < max_dma) {
166 z = ZONE_DMA;
167 rend = (cend < max_dma)? cend : max_dma;
168
169 } else if (cstart < max_low_pfn) {
170 z = ZONE_NORMAL;
171 rend = (cend < max_low_pfn)? cend : max_low_pfn;
172
173 } else {
174 z = ZONE_HIGHMEM;
175 rend = cend;
176 }
177 zones[z] += rend - cstart;
178 cstart = rend;
179 }
180}
181
182/* 136/*
183 * The SRAT table always lists ascending addresses, so can always 137 * The SRAT table always lists ascending addresses, so can always
184 * assume that the first "start" address that you see is the real 138 * assume that the first "start" address that you see is the real
@@ -223,7 +177,6 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
223 177
224 memset(pxm_bitmap, 0, sizeof(pxm_bitmap)); /* init proximity domain bitmap */ 178 memset(pxm_bitmap, 0, sizeof(pxm_bitmap)); /* init proximity domain bitmap */
225 memset(node_memory_chunk, 0, sizeof(node_memory_chunk)); 179 memset(node_memory_chunk, 0, sizeof(node_memory_chunk));
226 memset(zholes_size, 0, sizeof(zholes_size));
227 180
228 num_memory_chunks = 0; 181 num_memory_chunks = 0;
229 while (p < end) { 182 while (p < end) {
@@ -287,6 +240,7 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
287 printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n", 240 printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n",
288 j, chunk->nid, chunk->start_pfn, chunk->end_pfn); 241 j, chunk->nid, chunk->start_pfn, chunk->end_pfn);
289 node_read_chunk(chunk->nid, chunk); 242 node_read_chunk(chunk->nid, chunk);
243 add_active_range(chunk->nid, chunk->start_pfn, chunk->end_pfn);
290 } 244 }
291 245
292 for_each_online_node(nid) { 246 for_each_online_node(nid) {
@@ -395,57 +349,7 @@ int __init get_memcfg_from_srat(void)
395 return acpi20_parse_srat((struct acpi_table_srat *)header); 349 return acpi20_parse_srat((struct acpi_table_srat *)header);
396 } 350 }
397out_err: 351out_err:
352 remove_all_active_ranges();
398 printk("failed to get NUMA memory information from SRAT table\n"); 353 printk("failed to get NUMA memory information from SRAT table\n");
399 return 0; 354 return 0;
400} 355}
401
402/* For each node run the memory list to determine whether there are
403 * any memory holes. For each hole determine which ZONE they fall
404 * into.
405 *
406 * NOTE#1: this requires knowledge of the zone boundries and so
407 * _cannot_ be performed before those are calculated in setup_memory.
408 *
409 * NOTE#2: we rely on the fact that the memory chunks are ordered by
410 * start pfn number during setup.
411 */
412static void __init get_zholes_init(void)
413{
414 int nid;
415 int c;
416 int first;
417 unsigned long end = 0;
418
419 for_each_online_node(nid) {
420 first = 1;
421 for (c = 0; c < num_memory_chunks; c++){
422 if (node_memory_chunk[c].nid == nid) {
423 if (first) {
424 end = node_memory_chunk[c].end_pfn;
425 first = 0;
426
427 } else {
428 /* Record any gap between this chunk
429 * and the previous chunk on this node
430 * against the zones it spans.
431 */
432 chunk_to_zones(end,
433 node_memory_chunk[c].start_pfn,
434 &zholes_size[nid * MAX_NR_ZONES]);
435 }
436 }
437 }
438 }
439}
440
441unsigned long * __init get_zholes_size(int nid)
442{
443 if (!zholes_size_init) {
444 zholes_size_init++;
445 get_zholes_init();
446 }
447 if (nid >= MAX_NUMNODES || !node_online(nid))
448 printk("%s: nid = %d is invalid/offline. num_online_nodes = %d",
449 __FUNCTION__, nid, num_online_nodes());
450 return &zholes_size[nid * MAX_NR_ZONES];
451}