diff options
Diffstat (limited to 'xen/common/domain.c')
-rw-r--r-- | xen/common/domain.c | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/xen/common/domain.c b/xen/common/domain.c index 590548e101..ce45d66b45 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -224,6 +224,7 @@ struct domain *domain_create( spin_lock_init(&d->node_affinity_lock); d->node_affinity = NODE_MASK_ALL; + d->auto_node_affinity = 1; spin_lock_init(&d->shutdown_lock); d->shutdown_code = -1; @@ -364,11 +365,32 @@ void domain_update_node_affinity(struct domain *d) cpumask_or(cpumask, cpumask, online_affinity); } - for_each_online_node ( node ) - if ( cpumask_intersects(&node_to_cpumask(node), cpumask) ) - node_set(node, nodemask); + if ( d->auto_node_affinity ) + { + /* Node-affinity is automaically computed from all vcpu-affinities */ + for_each_online_node ( node ) + if ( cpumask_intersects(&node_to_cpumask(node), cpumask) ) + node_set(node, nodemask); + + d->node_affinity = nodemask; + } + else + { + /* Node-affinity is provided by someone else, just filter out cpus + * that are either offline or not in the affinity of any vcpus. */ + nodemask = d->node_affinity; + for_each_node_mask ( node, d->node_affinity ) + if ( !cpumask_intersects(&node_to_cpumask(node), cpumask) ) + node_clear(node, nodemask);//d->node_affinity); + + /* Avoid loosing track of node-affinity because of a bad + * vcpu-affinity has been specified. */ + if ( !nodes_empty(nodemask) ) + d->node_affinity = nodemask; + } + + sched_set_node_affinity(d, &d->node_affinity); - d->node_affinity = nodemask; spin_unlock(&d->node_affinity_lock); free_cpumask_var(online_affinity); @@ -376,6 +398,36 @@ 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) ) + return -EINVAL; + + spin_lock(&d->node_affinity_lock); + + /* + * Being/becoming explicitly affine to all nodes is not particularly + * useful. Let's take it as the `reset node affinity` command. + */ + if ( nodes_full(*affinity) ) + { + d->auto_node_affinity = 1; + goto out; + } + + d->auto_node_affinity = 0; + d->node_affinity = *affinity; + +out: + spin_unlock(&d->node_affinity_lock); + + domain_update_node_affinity(d); + + return 0; +} + + struct domain *get_domain_by_id(domid_t dom) { struct domain *d; |