# HG changeset patch # User Juergen Gross # Date 1327320724 -3600 # Node ID 5cf2063db3b5f6abe8c0b5dac09d07fe90920304 # Parent 137c16a83e4084b717a8a5685371800aeb313233 Reflect cpupool in numa node affinity (v2) In order to prefer node local memory for a domain the numa node locality info must be built according to the cpus belonging to the cpupool of the domain. Changes since v1: - switch to dynamically allocated cpumasks in domain_update_node_affinity() - introduce and use common macros for selecting cpupool based cpumasks Signed-off-by: juergen.gross@xxxxxxxxxxxxxx diff -r 137c16a83e40 -r 5cf2063db3b5 xen/common/cpupool.c --- a/xen/common/cpupool.c Mon Jan 23 09:42:12 2012 +0000 +++ b/xen/common/cpupool.c Mon Jan 23 13:12:04 2012 +0100 @@ -220,6 +220,7 @@ static int cpupool_assign_cpu_locked(str { int ret; struct cpupool *old; + struct domain *d; if ( (cpupool_moving_cpu == cpu) && (c != cpupool_cpu_moving) ) return -EBUSY; @@ -240,6 +241,14 @@ static int cpupool_assign_cpu_locked(str cpupool_cpu_moving = NULL; } cpumask_set_cpu(cpu, c->cpu_valid); + + rcu_read_lock(&domlist_read_lock); + for_each_domain_in_cpupool(d, c) + { + domain_update_node_affinity(d); + } + rcu_read_unlock(&domlist_read_lock); + return 0; } diff -r 137c16a83e40 -r 5cf2063db3b5 xen/common/domain.c --- a/xen/common/domain.c Mon Jan 23 09:42:12 2012 +0000 +++ b/xen/common/domain.c Mon Jan 23 13:12:04 2012 +0100 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -333,23 +334,38 @@ struct domain *domain_create( void domain_update_node_affinity(struct domain *d) { - cpumask_t cpumask; + cpumask_var_t cpumask; + cpumask_var_t online_affinity; + const cpumask_t *online; nodemask_t nodemask = NODE_MASK_NONE; struct vcpu *v; unsigned int node; - cpumask_clear(&cpumask); + if (!zalloc_cpumask_var(&cpumask)) + return; + if (!alloc_cpumask_var(&online_affinity)) + { + free_cpumask_var(cpumask); + return; + } + + online = cpupool_online_cpumask(d->cpupool); spin_lock(&d->node_affinity_lock); for_each_vcpu ( d, v ) - cpumask_or(&cpumask, &cpumask, v->cpu_affinity); + { + cpumask_and(online_affinity, v->cpu_affinity, online); + cpumask_or(cpumask, cpumask, online_affinity); + } for_each_online_node ( node ) - if ( cpumask_intersects(&node_to_cpumask(node), &cpumask) ) + if ( cpumask_intersects(&node_to_cpumask(node), cpumask) ) node_set(node, nodemask); d->node_affinity = nodemask; spin_unlock(&d->node_affinity_lock); + + free_cpumask_var(cpumask); } diff -r 137c16a83e40 -r 5cf2063db3b5 xen/common/domctl.c --- a/xen/common/domctl.c Mon Jan 23 09:42:12 2012 +0000 +++ b/xen/common/domctl.c Mon Jan 23 13:12:04 2012 +0100 @@ -518,7 +518,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc goto maxvcpu_out; ret = -ENOMEM; - online = (d->cpupool == NULL) ? &cpu_online_map : d->cpupool->cpu_valid; + online = cpupool_online_cpumask(d->cpupool); if ( max > d->max_vcpus ) { struct vcpu **vcpus; diff -r 137c16a83e40 -r 5cf2063db3b5 xen/common/sched_credit.c --- a/xen/common/sched_credit.c Mon Jan 23 09:42:12 2012 +0000 +++ b/xen/common/sched_credit.c Mon Jan 23 13:12:04 2012 +0100 @@ -72,8 +72,6 @@ #define CSCHED_VCPU(_vcpu) ((struct csched_vcpu *) (_vcpu)->sched_priv) #define CSCHED_DOM(_dom) ((struct csched_dom *) (_dom)->sched_priv) #define RUNQ(_cpu) (&(CSCHED_PCPU(_cpu)->runq)) -#define CSCHED_CPUONLINE(_pool) \ - (((_pool) == NULL) ? &cpupool_free_cpus : (_pool)->cpu_valid) /* @@ -471,7 +469,7 @@ _csched_cpu_pick(const struct scheduler * Pick from online CPUs in VCPU's affinity mask, giving a * preference to its current processor if it's in there. */ - online = CSCHED_CPUONLINE(vc->domain->cpupool); + online = cpupool_scheduler_cpumask(vc->domain->cpupool); cpumask_and(&cpus, online, vc->cpu_affinity); cpu = cpumask_test_cpu(vc->processor, &cpus) ? vc->processor @@ -1230,7 +1228,7 @@ csched_load_balance(struct csched_privat int peer_cpu; BUG_ON( cpu != snext->vcpu->processor ); - online = CSCHED_CPUONLINE(per_cpu(cpupool, cpu)); + online = cpupool_scheduler_cpumask(per_cpu(cpupool, cpu)); /* If this CPU is going offline we shouldn't steal work. */ if ( unlikely(!cpumask_test_cpu(cpu, online)) ) diff -r 137c16a83e40 -r 5cf2063db3b5 xen/common/sched_credit2.c --- a/xen/common/sched_credit2.c Mon Jan 23 09:42:12 2012 +0000 +++ b/xen/common/sched_credit2.c Mon Jan 23 13:12:04 2012 +0100 @@ -169,8 +169,6 @@ integer_param("sched_credit2_migrate_res ((struct csched_private *)((_ops)->sched_data)) #define CSCHED_VCPU(_vcpu) ((struct csched_vcpu *) (_vcpu)->sched_priv) #define CSCHED_DOM(_dom) ((struct csched_dom *) (_dom)->sched_priv) -#define CSCHED_CPUONLINE(_pool) \ - (((_pool) == NULL) ? &cpupool_free_cpus : (_pool)->cpu_valid) /* CPU to runq_id macro */ #define c2r(_ops, _cpu) (CSCHED_PRIV(_ops)->runq_map[(_cpu)]) /* CPU to runqueue struct macro */ diff -r 137c16a83e40 -r 5cf2063db3b5 xen/common/sched_sedf.c --- a/xen/common/sched_sedf.c Mon Jan 23 09:42:12 2012 +0000 +++ b/xen/common/sched_sedf.c Mon Jan 23 13:12:04 2012 +0100 @@ -12,9 +12,6 @@ #include #include #include - -#define SEDF_CPUONLINE(_pool) \ - (((_pool) == NULL) ? &cpupool_free_cpus : (_pool)->cpu_valid) #ifndef NDEBUG #define SEDF_STATS @@ -397,7 +394,7 @@ static int sedf_pick_cpu(const struct sc cpumask_t online_affinity; cpumask_t *online; - online = SEDF_CPUONLINE(v->domain->cpupool); + online = cpupool_scheduler_cpumask(v->domain->cpupool); cpumask_and(&online_affinity, v->cpu_affinity, online); return cpumask_first(&online_affinity); } @@ -801,7 +798,8 @@ static struct task_slice sedf_do_schedul */ if ( tasklet_work_scheduled || (list_empty(runq) && list_empty(waitq)) || - unlikely(!cpumask_test_cpu(cpu, SEDF_CPUONLINE(per_cpu(cpupool, cpu)))) ) + unlikely(!cpumask_test_cpu(cpu, + cpupool_scheduler_cpumask(per_cpu(cpupool, cpu)))) ) { ret.task = IDLETASK(cpu); ret.time = SECONDS(1); diff -r 137c16a83e40 -r 5cf2063db3b5 xen/common/schedule.c --- a/xen/common/schedule.c Mon Jan 23 09:42:12 2012 +0000 +++ b/xen/common/schedule.c Mon Jan 23 13:12:04 2012 +0100 @@ -77,9 +77,7 @@ static struct scheduler __read_mostly op #define DOM2OP(_d) (((_d)->cpupool == NULL) ? &ops : ((_d)->cpupool->sched)) #define VCPU2OP(_v) (DOM2OP((_v)->domain)) -#define VCPU2ONLINE(_v) \ - (((_v)->domain->cpupool == NULL) ? &cpu_online_map \ - : (_v)->domain->cpupool->cpu_valid) +#define VCPU2ONLINE(_v) cpupool_online_cpumask((_v)->domain->cpupool) static inline void trace_runstate_change(struct vcpu *v, int new_state) { @@ -282,11 +280,12 @@ int sched_move_domain(struct domain *d, SCHED_OP(VCPU2OP(v), insert_vcpu, v); } - domain_update_node_affinity(d); d->cpupool = c; SCHED_OP(DOM2OP(d), free_domdata, d->sched_priv); d->sched_priv = domdata; + + domain_update_node_affinity(d); domain_unpause(d); @@ -537,7 +536,6 @@ int cpu_disable_scheduler(unsigned int c struct cpupool *c; cpumask_t online_affinity; int ret = 0; - bool_t affinity_broken; c = per_cpu(cpupool, cpu); if ( c == NULL ) @@ -545,8 +543,6 @@ int cpu_disable_scheduler(unsigned int c for_each_domain_in_cpupool ( d, c ) { - affinity_broken = 0; - for_each_vcpu ( d, v ) { vcpu_schedule_lock_irq(v); @@ -558,7 +554,6 @@ int cpu_disable_scheduler(unsigned int c printk("Breaking vcpu affinity for domain %d vcpu %d\n", v->domain->domain_id, v->vcpu_id); cpumask_setall(v->cpu_affinity); - affinity_broken = 1; } if ( v->processor == cpu ) @@ -582,8 +577,7 @@ int cpu_disable_scheduler(unsigned int c ret = -EAGAIN; } - if ( affinity_broken ) - domain_update_node_affinity(d); + domain_update_node_affinity(d); } return ret; @@ -1418,7 +1412,7 @@ void schedule_dump(struct cpupool *c) cpumask_t *cpus; sched = (c == NULL) ? &ops : c->sched; - cpus = (c == NULL) ? &cpupool_free_cpus : c->cpu_valid; + cpus = cpupool_scheduler_cpumask(c); printk("Scheduler: %s (%s)\n", sched->name, sched->opt_name); SCHED_OP(sched, dump_settings); diff -r 137c16a83e40 -r 5cf2063db3b5 xen/include/xen/sched-if.h --- a/xen/include/xen/sched-if.h Mon Jan 23 09:42:12 2012 +0000 +++ b/xen/include/xen/sched-if.h Mon Jan 23 13:12:04 2012 +0100 @@ -204,4 +204,8 @@ struct cpupool atomic_t refcnt; }; +#define cpupool_scheduler_cpumask(_pool) \ + (((_pool) == NULL) ? &cpupool_free_cpus : (_pool)->cpu_valid) +#define cpupool_online_cpumask(_pool) \ + (((_pool) == NULL) ? &cpu_online_map : (_pool)->cpu_valid) #endif /* __XEN_SCHED_IF_H__ */