[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2 6/7] xen/page_alloc: Check per-node claims in alloc_heap_pages()
Extend the claim checks in alloc_heap_pages() to NUMA claims. Signed-off-by: Bernhard Kaindl <bernhard.kaindl@xxxxxxxxx> Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@xxxxxxx> --- Changes since v1: - No longer require the memflags & MEMF_exact_node for using claims - If the NUMA node is not passed in memflags, get the NUMA node to conume claims from using the claim itself and confirm it using the domain's d->node_affinity, which is where get_free_buddy will allocate from. This also eases the conversion to multi-node claim usage as memflags in inherently single-node. --- xen/common/page_alloc.c | 46 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 63ecd74dcc..12e1d6a049 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -1027,6 +1027,48 @@ static void init_free_page_fields(struct page_info *pg) page_set_owner(pg, NULL); } +/* + * Check if a heap allocation is allowed (helper for alloc_heap_pages) + */ +static bool can_alloc(const struct domain *d, unsigned int memflags, + unsigned long request) +{ + nodeid_t node = MEMF_get_node(memflags); + + /* + * If memflags don't define a node to allocate from, get_free_buddy() will + * use d->node_affinity for the allocation: Allow the allocation to + * take advantage of it when the claimed node is exactly d->node_affinity: + */ + if ( node == NUMA_NO_NODE && d && d->claim_node != NUMA_NO_NODE ) + { + nodemask_t claim_node = nodemask_of_node(d->claim_node); + + if (nodes_equal(d->node_affinity, claim_node)) + node = d->claim_node; + } + + if ( outstanding_claims + request <= total_avail_pages && /* host-wide, */ + (node == NUMA_NO_NODE || /* if the alloc is node-specific, then also */ + per_node_outstanding_claims[node] + request <= /* check per-node */ + per_node_avail_pages[node]) ) + return true; + + /* + * The requested allocation can only be satisfied by outstanding claims. + * Claimed memory is considered unavailable unless the request + * is made by a domain with sufficient unclaimed pages. + * + * Only allow if the allocation matches the available claims of the domain. + * For host-wide allocs and claims, node == d->claim_node == NUMA_NO_NODE. + * + * Only refcounted allocs attributed to domains may have been claimed: + * Not refcounted allocs cannot consume claimed memory. + */ + return d && d->claim_node == node && d->outstanding_pages >= request && + !(memflags & MEMF_no_refcount); +} + /* Allocate 2^@order contiguous pages. */ static struct page_info *alloc_heap_pages( unsigned int zone_lo, unsigned int zone_hi, @@ -1057,9 +1099,7 @@ static struct page_info *alloc_heap_pages( * Claimed memory is considered unavailable unless the request * is made by a domain with sufficient unclaimed pages. */ - if ( (outstanding_claims + request > total_avail_pages) && - ((memflags & MEMF_no_refcount) || - !d || d->outstanding_pages < request) ) + if ( !can_alloc(d, memflags, request) ) { spin_unlock(&heap_lock); return NULL; -- 2.43.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |