]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86_64/mm/numa.c
Merge by hand (conflicts in sr.c)
[linux-2.6-omap-h63xx.git] / arch / x86_64 / mm / numa.c
index ac61c186eb0218862f59e8638bef6ef918e11064..6a156f5692ae78a520a4dc0694a78f70b4a6c71a 100644 (file)
@@ -36,34 +36,36 @@ int numa_off __initdata;
 int __init compute_hash_shift(struct node *nodes, int numnodes)
 {
        int i; 
-       int shift = 24;
-       u64 addr;
+       int shift = 20;
+       unsigned long addr,maxend=0;
        
-       /* When in doubt use brute force. */
-       while (shift < 48) { 
-               memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); 
-               for (i = 0; i < numnodes; i++) {
-                       if (nodes[i].start == nodes[i].end) 
-                               continue;
-                       for (addr = nodes[i].start; 
-                            addr < nodes[i].end; 
-                            addr += (1UL << shift)) {
-                               if (memnodemap[addr >> shift] != 0xff && 
-                                   memnodemap[addr >> shift] != i) { 
-                                       printk(KERN_INFO 
-                                           "node %d shift %d addr %Lx conflict %d\n", 
-                                              i, shift, addr, memnodemap[addr>>shift]);
-                                       goto next; 
-                               } 
-                               memnodemap[addr >> shift] = i; 
+       for (i = 0; i < numnodes; i++)
+               if ((nodes[i].start != nodes[i].end) && (nodes[i].end > maxend))
+                               maxend = nodes[i].end;
+
+       while ((1UL << shift) <  (maxend / NODEMAPSIZE))
+               shift++;
+
+       printk (KERN_DEBUG"Using %d for the hash shift. Max adder is %lx \n",
+                       shift,maxend);
+       memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE);
+       for (i = 0; i < numnodes; i++) {
+               if (nodes[i].start == nodes[i].end)
+                       continue;
+               for (addr = nodes[i].start;
+                    addr < nodes[i].end;
+                    addr += (1UL << shift)) {
+                       if (memnodemap[addr >> shift] != 0xff) {
+                               printk(KERN_INFO
+       "Your memory is not aligned you need to rebuild your kernel "
+       "with a bigger NODEMAPSIZE shift=%d adder=%lu\n",
+                                       shift,addr);
+                               return -1;
                        } 
+                       memnodemap[addr >> shift] = i;
                } 
-               return shift; 
-       next:
-               shift++; 
        } 
-       memset(memnodemap,0,sizeof(*memnodemap) * NODEMAPSIZE); 
-       return -1; 
+       return shift;
 }
 
 #ifdef CONFIG_SPARSEMEM
@@ -124,9 +126,11 @@ void __init setup_node_zones(int nodeid)
 { 
        unsigned long start_pfn, end_pfn; 
        unsigned long zones[MAX_NR_ZONES];
+       unsigned long holes[MAX_NR_ZONES];
        unsigned long dma_end_pfn;
 
        memset(zones, 0, sizeof(unsigned long) * MAX_NR_ZONES); 
+       memset(holes, 0, sizeof(unsigned long) * MAX_NR_ZONES);
 
        start_pfn = node_start_pfn(nodeid);
        end_pfn = node_end_pfn(nodeid);
@@ -137,13 +141,17 @@ void __init setup_node_zones(int nodeid)
        dma_end_pfn = __pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT; 
        if (start_pfn < dma_end_pfn) { 
                zones[ZONE_DMA] = dma_end_pfn - start_pfn;
+               holes[ZONE_DMA] = e820_hole_size(start_pfn, dma_end_pfn);
                zones[ZONE_NORMAL] = end_pfn - dma_end_pfn; 
+               holes[ZONE_NORMAL] = e820_hole_size(dma_end_pfn, end_pfn);
+
        } else { 
                zones[ZONE_NORMAL] = end_pfn - start_pfn; 
+               holes[ZONE_NORMAL] = e820_hole_size(start_pfn, end_pfn);
        } 
     
        free_area_init_node(nodeid, NODE_DATA(nodeid), zones,
-                           start_pfn, NULL); 
+                           start_pfn, holes);
 } 
 
 void __init numa_init_array(void)