diff --git a/xen/common/memory.c b/xen/common/memory.c --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -545,6 +545,8 @@ long do_memory_op(unsigned long cmd, XEN } 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 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -300,11 +300,17 @@ static struct page_info *alloc_heap_page unsigned int i, j, zone = 0; unsigned int num_nodes = num_online_nodes(); unsigned long request = 1UL << order; + unsigned int exact_node_request; 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; + } else { + exact_node_request = (memflags & MEMF_exact_node); + } ASSERT(node >= 0); ASSERT(zone_lo <= zone_hi); @@ -342,6 +348,8 @@ static struct page_info *alloc_heap_page 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) @@ -357,6 +365,7 @@ static struct page_info *alloc_heap_page 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 --- 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 --- 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