]> xenbits.xensource.com Git - xen.git/commitdiff
page-alloc/x86: don't restrict DMA heap to node 0
authorJan Beulich <jbeulich@suse.com>
Fri, 26 Aug 2016 08:31:25 +0000 (10:31 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 26 Aug 2016 08:31:25 +0000 (10:31 +0200)
When node zero has no memory, the DMA bit width will end up getting set
to 9, which is obviously not helpful to hold back a reasonable amount
of low enough memory for Dom0 to use for DMA purposes. Find the lowest
node with memory below 4Gb instead.

Introduce arch_get_dma_bitsize() to keep this arch-specific logic out
of common code.

Also adjust the original calculation: I think the subtraction of 1
should have been part of the flsl() argument rather than getting
applied to its result. And while previously the division by 4 was valid
to be done on the flsl() result, this now also needs to be converted,
as is should only be applied to the spanned pages value.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
master commit: d0d6597d3d682f324b6a79e3278e6f5bb6bad153
master date: 2016-08-11 13:35:50 +0200

xen/arch/x86/numa.c
xen/common/page_alloc.c
xen/include/asm-arm/numa.h
xen/include/asm-x86/numa.h

index a526f77d0865a42d92e202adb79f8c30b0701687..c78ed36746e175175064d26270582bde7e78e582 100644 (file)
@@ -354,11 +354,25 @@ void __init init_cpu_to_node(void)
     }
 }
 
-EXPORT_SYMBOL(cpu_to_node);
-EXPORT_SYMBOL(node_to_cpumask);
-EXPORT_SYMBOL(memnode_shift);
-EXPORT_SYMBOL(memnodemap);
-EXPORT_SYMBOL(node_data);
+unsigned int __init arch_get_dma_bitsize(void)
+{
+    unsigned int node;
+
+    for_each_online_node(node)
+        if ( node_spanned_pages(node) &&
+             !(node_start_pfn(node) >> (32 - PAGE_SHIFT)) )
+            break;
+    if ( node >= MAX_NUMNODES )
+        panic("No node with memory below 4Gb");
+
+    /*
+     * Try to not reserve the whole node's memory for DMA, but dividing
+     * its spanned pages by (arbitrarily chosen) 4.
+     */
+    return min_t(unsigned int,
+                 fls(node_start_pfn(node) + node_spanned_pages(node) / 4 - 1)
+                 + PAGE_SHIFT, 32);
+}
 
 static void dump_numa(unsigned char key)
 {
index fc6db333390777df57466d71345285044597bdd9..926a8b2e9b5c9bd30c6feaf1d096421ec18f3433 100644 (file)
@@ -1267,16 +1267,7 @@ void __init end_boot_allocator(void)
     init_heap_pages(virt_to_page(bootmem_region_list), 1);
 
     if ( !dma_bitsize && (num_online_nodes() > 1) )
-    {
-#ifdef CONFIG_X86
-        dma_bitsize = min_t(unsigned int,
-                            fls(NODE_DATA(0)->node_spanned_pages) - 1
-                            + PAGE_SHIFT - 2,
-                            32);
-#else
-        dma_bitsize = 32;
-#endif
-    }
+        dma_bitsize = arch_get_dma_bitsize();
 
     printk("Domain heap initialised");
     if ( dma_bitsize )
index 06a9d5a45363df2493d9c3aa90f2731f8a7da9d2..6f72b653831e67fe7c192f355ac411f652dba484 100644 (file)
@@ -15,6 +15,11 @@ static inline __attribute__((pure)) int phys_to_nid(paddr_t addr)
 #define node_start_pfn(nid) (pdx_to_pfn(frametable_base_pdx))
 #define __node_distance(a, b) (20)
 
+static inline unsigned int arch_get_dma_bitsize(void)
+{
+    return 32;
+}
+
 #endif /* __ARCH_ARM_NUMA_H */
 /*
  * Local variables:
index 59598607416d99d9b96e9d80e86a9adfd5eac04a..53ac9802eabdbc61d9d6ff844043b05893bee98c 100644 (file)
@@ -84,5 +84,6 @@ extern int valid_numa_range(u64 start, u64 end, int node);
 
 void srat_parse_regions(u64 addr);
 extern int __node_distance(int a, int b);
+unsigned int arch_get_dma_bitsize(void);
 
 #endif