|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] 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#master
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |