vserver 1.9.5.x5
[linux-2.6.git] / arch / x86_64 / mm / numa.c
index e6746a2..fd9f25d 100644 (file)
 #include <linux/mmzone.h>
 #include <linux/ctype.h>
 #include <linux/module.h>
+#include <linux/nodemask.h>
+
 #include <asm/e820.h>
 #include <asm/proto.h>
 #include <asm/dma.h>
 #include <asm/numa.h>
+#include <asm/acpi.h>
 
 #ifndef Dprintk
 #define Dprintk(x...)
 #endif
 
-struct pglist_data *node_data[MAXNODE];
+struct pglist_data *node_data[MAX_NUMNODES];
 bootmem_data_t plat_node_bdata[MAX_NUMNODES];
 
 int memnode_shift;
 u8  memnodemap[NODEMAPSIZE];
 
-unsigned char cpu_to_node[NR_CPUS];  
-cpumask_t     node_to_cpumask[MAXNODE]; 
-
-static int numa_off __initdata; 
+unsigned char cpu_to_node[NR_CPUS] = { [0 ... NR_CPUS-1] = NUMA_NO_NODE };
+cpumask_t     node_to_cpumask[MAX_NUMNODES];
 
-unsigned long nodes_present; 
+int numa_off __initdata;
 
-int __init compute_hash_shift(struct node *nodes)
+int __init compute_hash_shift(struct node *nodes, int numnodes)
 {
        int i; 
        int shift = 24;
@@ -41,7 +42,7 @@ int __init compute_hash_shift(struct node *nodes)
        /* When in doubt use brute force. */
        while (shift < 48) { 
                memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); 
-               for (i = 0; i < numnodes; i++) { 
+               for (i = 0; i < numnodes; i++) {
                        if (nodes[i].start == nodes[i].end) 
                                continue;
                        for (addr = nodes[i].start; 
@@ -107,8 +108,6 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
 
        reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); 
        reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT);
-       if (nodeid + 1 > numnodes)
-               numnodes = nodeid + 1;
        node_set_online(nodeid);
 } 
 
@@ -148,13 +147,12 @@ void __init numa_init_array(void)
           CPUs, as the number of CPUs is not known yet. 
           We round robin the existing nodes. */
        rr = 0;
-       for (i = 0; i < MAXNODE; i++) {
-               if (node_online(i))
+       for (i = 0; i < NR_CPUS; i++) {
+               if (cpu_to_node[i] != NUMA_NO_NODE)
                        continue;
-               rr = find_next_bit(node_online_map, MAX_NUMNODES, rr);
+               rr = next_node(rr, node_online_map);
                if (rr == MAX_NUMNODES)
-                       rr = find_first_bit(node_online_map, MAX_NUMNODES);
-               node_data[i] = node_data[rr];
+                       rr = first_node(node_online_map);
                cpu_to_node[i] = rr;
                rr++; 
        }
@@ -162,13 +160,14 @@ void __init numa_init_array(void)
        set_bit(0, &node_to_cpumask[cpu_to_node(0)]);
 }
 
+#ifdef CONFIG_NUMA_EMU
 int numa_fake __initdata = 0;
 
 /* Numa emulation */
 static int numa_emulation(unsigned long start_pfn, unsigned long end_pfn)
 {
        int i;
-       struct node nodes[MAXNODE];
+       struct node nodes[MAX_NUMNODES];
        unsigned long sz = ((end_pfn - start_pfn)<<PAGE_SHIFT) / numa_fake;
 
        /* Kludge needed for the hash function */
@@ -193,26 +192,35 @@ static int numa_emulation(unsigned long start_pfn, unsigned long end_pfn)
                       i,
                       nodes[i].start, nodes[i].end,
                       (nodes[i].end - nodes[i].start) >> 20);
+               node_set_online(i);
        }
-       numnodes = numa_fake;
-       memnode_shift = compute_hash_shift(nodes);
+       memnode_shift = compute_hash_shift(nodes, numa_fake);
        if (memnode_shift < 0) {
                memnode_shift = 0;
                printk(KERN_ERR "No NUMA hash function found. Emulation disabled.\n");
                return -1;
        }
-       for (i = 0; i < numa_fake; i++)
+       for_each_online_node(i)
                setup_node_bootmem(i, nodes[i].start, nodes[i].end);
        numa_init_array();
        return 0;
 }
+#endif
 
 void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
 { 
        int i;
 
+#ifdef CONFIG_NUMA_EMU
        if (numa_fake && !numa_emulation(start_pfn, end_pfn))
                return;
+#endif
+
+#ifdef CONFIG_ACPI_NUMA
+       if (!numa_off && !acpi_scan_nodes(start_pfn << PAGE_SHIFT,
+                                         end_pfn << PAGE_SHIFT))
+               return;
+#endif
 
 #ifdef CONFIG_K8_NUMA
        if (!numa_off && !k8_scan_nodes(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT))
@@ -227,11 +235,12 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
                /* setup dummy node covering all memory */ 
        memnode_shift = 63; 
        memnodemap[0] = 0;
-       numnodes = 1;
+       nodes_clear(node_online_map);
+       node_set_online(0);
        for (i = 0; i < NR_CPUS; i++)
                cpu_to_node[i] = 0;
        node_to_cpumask[0] = cpumask_of_cpu(0);
-       setup_node_bootmem(0, start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
+       setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
 }
 
 __init void numa_add_cpu(int cpu)
@@ -245,7 +254,7 @@ unsigned long __init numa_free_all_bootmem(void)
 { 
        int i;
        unsigned long pages = 0;
-       for_all_nodes(i) {
+       for_each_online_node(i) {
                pages += free_all_bootmem_node(NODE_DATA(i));
        }
        return pages;
@@ -254,7 +263,7 @@ unsigned long __init numa_free_all_bootmem(void)
 void __init paging_init(void)
 { 
        int i;
-       for_all_nodes(i) { 
+       for_each_online_node(i) {
                setup_node_zones(i); 
        }
 } 
@@ -262,13 +271,19 @@ void __init paging_init(void)
 /* [numa=off] */
 __init int numa_setup(char *opt) 
 { 
-       if (!strcmp(opt,"off"))
+       if (!strncmp(opt,"off",3))
                numa_off = 1;
+#ifdef CONFIG_NUMA_EMU
        if(!strncmp(opt, "fake=", 5)) {
                numa_fake = simple_strtoul(opt+5,NULL,0); ;
                if (numa_fake >= MAX_NUMNODES)
                        numa_fake = MAX_NUMNODES;
        }
+#endif
+#ifdef CONFIG_ACPI_NUMA
+       if (!strncmp(opt,"noacpi",6))
+               acpi_numa = -1;
+#endif
        return 1;
 }