[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] xen/page-alloc: Clamp get_free_buddy() to online nodes
commit 1ae0db5e48106498dcb3b9fe2dd3e74830e284c4 Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> AuthorDate: Mon Jun 24 16:38:36 2019 +0100 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Wed Jul 31 14:18:31 2019 +0100 xen/page-alloc: Clamp get_free_buddy() to online nodes d->node_affinity defaults to NODE_MASK_ALL which has bits set outside of node_online_map. This in turn causes the loop in get_free_buddy() to waste effort iterating over offline nodes. Always clamp d->node_affinity to node_online_map. This in turn requires ensuring that d->node_affinity intersects with node_online_map, and there is one case via XEN_DOMCTL_setnodeaffinity where a disjoint mask can end up being specified. Tighten up the hypercall check, because there is no plausible reason to select a node affinity which is disjoint with the system, and leave get_free_buddy() with an assertion to the same effect, but with a runtime-safe fallback to the full online node map. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- xen/common/domain.c | 4 ++-- xen/common/page_alloc.c | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/xen/common/domain.c b/xen/common/domain.c index df523c9ce4..744b572195 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -627,8 +627,8 @@ void domain_update_node_affinity(struct domain *d) int domain_set_node_affinity(struct domain *d, const nodemask_t *affinity) { - /* Being affine with no nodes is just wrong */ - if ( nodes_empty(*affinity) ) + /* Being disjoint with the system is just wrong. */ + if ( !nodes_intersects(*affinity, node_online_map) ) return -EINVAL; spin_lock(&d->node_affinity_lock); diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 44a72d0b19..4b16ef0d54 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -811,11 +811,27 @@ static struct page_info *get_free_buddy(unsigned int zone_lo, const struct domain *d) { nodeid_t first, node = MEMF_get_node(memflags), req_node = node; - nodemask_t nodemask = d ? d->node_affinity : node_online_map; + nodemask_t nodemask = node_online_map; unsigned int j, zone, nodemask_retry = 0; struct page_info *pg; bool use_unscrubbed = (memflags & MEMF_no_scrub); + /* + * d->node_affinity is our preferred allocation set if provided, but it + * may have bits set outside of node_online_map. Clamp it. + */ + if ( d ) + { + /* + * It is the callers responsibility to ensure that d->node_affinity + * isn't complete junk. + */ + if ( nodes_intersects(nodemask, d->node_affinity) ) + nodes_and(nodemask, nodemask, d->node_affinity); + else + ASSERT_UNREACHABLE(); + } + if ( node == NUMA_NO_NODE ) { if ( d != NULL ) -- generated by git-patchbot for /home/xen/git/xen.git#staging _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |