aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xen/common/memory.c2
-rw-r--r--xen/common/page_alloc.c8
-rw-r--r--xen/include/public/memory.h3
-rw-r--r--xen/include/xen/mm.h2
4 files changed, 15 insertions, 0 deletions
diff --git a/xen/common/memory.c b/xen/common/memory.c
index c7caa074c0..924f07a1e1 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -545,6 +545,8 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE(void) arg)
}
args.memflags |= MEMF_node(XENMEMF_get_node(reservation.mem_flags));
+ if (reservation.mem_flags & XENMEMF_exact_node_request)
+ args.memflags |= MEMF_exact_node;
if ( op == XENMEM_populate_physmap
&& (reservation.mem_flags & XENMEMF_populate_on_demand) )
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index 10c6b22093..1588a2a092 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -300,11 +300,15 @@ static struct page_info *alloc_heap_pages(
unsigned int i, j, zone = 0;
unsigned int num_nodes = num_online_nodes();
unsigned long request = 1UL << order;
+ bool_t exact_node_request = !!(memflags & MEMF_exact_node);
cpumask_t extra_cpus_mask, mask;
struct page_info *pg;
if ( node == NUMA_NO_NODE )
+ {
node = cpu_to_node(smp_processor_id());
+ exact_node_request = 0;
+ }
ASSERT(node >= 0);
ASSERT(zone_lo <= zone_hi);
@@ -345,6 +349,9 @@ static struct page_info *alloc_heap_pages(
goto found;
} while ( zone-- > zone_lo ); /* careful: unsigned zone may wrap */
+ if ( exact_node_request )
+ goto not_found;
+
/* Pick next node, wrapping around if needed. */
node = next_node(node, node_online_map);
if (node == MAX_NUMNODES)
@@ -360,6 +367,7 @@ static struct page_info *alloc_heap_pages(
return pg;
}
+ not_found:
/* No suitable memory blocks. Fail the request. */
spin_unlock(&heap_lock);
return NULL;
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index 883a17d8dd..08355e3c3c 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -52,6 +52,9 @@
#define XENMEMF_get_node(x) ((((x) >> 8) - 1) & 0xffu)
/* Flag to populate physmap with populate-on-demand entries */
#define XENMEMF_populate_on_demand (1<<16)
+/* Flag to request allocation only from the node specified */
+#define XENMEMF_exact_node_request (1<<17)
+#define XENMEMF_exact_node(n) (XENMEMF_node(n) | XENMEMF_exact_node_request)
#endif
struct xen_memory_reservation {
diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h
index 612a11c39b..63c47099f7 100644
--- a/xen/include/xen/mm.h
+++ b/xen/include/xen/mm.h
@@ -82,6 +82,8 @@ int assign_pages(
#define MEMF_tmem (1U<<_MEMF_tmem)
#define _MEMF_no_dma 3
#define MEMF_no_dma (1U<<_MEMF_no_dma)
+#define _MEMF_exact_node 4
+#define MEMF_exact_node (1U<<_MEMF_exact_node)
#define _MEMF_node 8
#define MEMF_node(n) ((((n)+1)&0xff)<<_MEMF_node)
#define _MEMF_bits 24