xen: sched / cpupool: fixes and improvements, mostly for when suspend/resume is involved
v2 cover xen: sched / cpupool: fixes and improvements, mostly for when suspend/resume is involved
Hello,
Take 2 of this series:
http://lists.xenproject.org/archives/html/xen-devel/2015-06/msg04137.html
There has not been much to do wrt v1, and the series has all the acks it requires, IMO, with (maybe, see below) the exception of patch 4.
Basically, I improved the changelog of patch 2, as Andrew requested, and I made the adjustemed to patch 4 that George Suggested (for more details, check the changelogs).
About patch 4: formally, it's missing George's ack. His comments to the patch are here:
http://osdir.com/ml/general/2015-07/msg02413.html
He gave a few suggestions, explicitly stating that no action was required. He also made a comment at the bottom, which I incorporated in this new version. However, he did not formally state that, with that change, I could consider the patch acked, so, although it looked like so, I did not put the tag in there.
I guess it will be up to the committers to judge, or we can just wait for Monday, or whenever George will have time to look at this again. In fact, I'm not saying all this to push or anything, I just wanted to provide a clear picture of the situation. :-)
There is a git branch with this version of the series here:
git://xenbits.xen.org/people/dariof/xen.git rel/cpupool/sched-fixes-v2
http://xenbits.xen.org/gitweb/?p=people/dariof/xen.git;a=shortlog;h=refs/heads/rel/cpupool/sched-fixes-v2
If the SEDF removal series goes in before this, I've preparred a branch with this series stacked on top of the SEDF one, in case it helps (of course, I can just rebase and resubmit, no big deal):
git://xenbits.xen.org/people/dariof/xen.git tmp/nosedf_cpupsched
http://xenbits.xen.org/gitweb/?p=people/dariof/xen.git;a=shortlog;h=refs/heads/tmp/nosedf_cpupsched
Thnaks and Regards,
Dario
---
Dario Faggioli (4):
xen: sched: avoid dumping duplicate information
xen: x86 / cpupool: clear the proper cpu_valid bit on pCPU teardown
xen: credit1: properly deal with pCPUs not in any cpupool
xen: sched: get rid of cpupool_scheduler_cpumask()
xen/arch/x86/smpboot.c | 1 - xen/common/cpupool.c | 8 +++++--- xen/common/domain.c | 5 +++-- xen/common/domctl.c | 4 ++-- xen/common/sched_arinc653.c | 2 +- xen/common/sched_credit.c | 25 ++++++++++++++++--------- xen/common/sched_rt.c | 12 ++++++------ xen/common/sched_sedf.c | 5 +++-- xen/common/schedule.c | 20 ++++++++++++++------ xen/include/xen/sched-if.h | 12 ++++++++++-- 10 files changed, 60 insertions(+), 34 deletions(-)
--
<<This happens because I choose it to happen!>> (Raistlin Majere)
-----------------------------------------------------------------
Dario Faggioli, Ph.D, http://about.me/dario.faggioli
Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
PATCH v2 1/4 xen: sched: avoid dumping duplicate information
When dumping scheduling information (debug key 'r'), what we print as 'Idle cpupool' is pretty much the same of what we print immediately after as 'Cpupool0'. In fact, if there are no pCPUs outside of any cpupools, it is exactly the same.
If there are free pCPUs, there is some valuable information, but still a lot of duplication:
(XEN) Online Cpus: 0-15
(XEN) Free Cpus: 8
(XEN) Idle cpupool:
(XEN) Scheduler: SMP Credit Scheduler (credit) (XEN) info:
(XEN) ncpus = 13
(XEN) master = 0
(XEN) credit = 3900
(XEN) credit balance = 45
(XEN) weight = 1280
(XEN) runq_sort = 11820
(XEN) default-weight = 256
(XEN) tslice = 30ms
(XEN) ratelimit = 1000us
(XEN) credits per msec = 10
(XEN) ticks per tslice = 3
(XEN) migration delay = 0us
(XEN) idlers: 00000000,00006d29
(XEN) active vcpus:
(XEN) 1: [1.7] pri=-1 flags=0 cpu=15 credit=-116 [w=256,cap=0] (84+300) {a/i=22/21 m=18+5 (k=0)}
(XEN) 2: [1.3] pri=0 flags=0 cpu=1 credit=-113 [w=256,cap=0] (87+300) {a/i=37/36 m=11+544 (k=0)}
(XEN) 3: [0.15] pri=-1 flags=0 cpu=4 credit=95 [w=256,cap=0] (210+300) {a/i=127/126 m=108+9 (k=0)}
(XEN) 4: [0.10] pri=-2 flags=0 cpu=12 credit=-287 [w=256,cap=0] (-84+300) {a/i=163/162 m=36+568 (k=0)}
(XEN) 5: [0.7] pri=-2 flags=0 cpu=2 credit=-242 [w=256,cap=0] (-42+300) {a/i=129/128 m=16+50 (k=0)}
(XEN) CPU[08] sort=5791, sibling=00000000,00000300, core=00000000,0000ff00
(XEN) run: [32767.8] pri=-64 flags=0 cpu=8
(XEN) Cpupool 0:
(XEN) Cpus: 0-5,10-15
(XEN) Scheduler: SMP Credit Scheduler (credit)
(XEN) info:
(XEN) ncpus = 13
(XEN) master = 0
(XEN) credit = 3900
(XEN) credit balance = 45
(XEN) weight = 1280
(XEN) runq_sort = 11820
(XEN) default-weight = 256
(XEN) tslice = 30ms
(XEN) ratelimit = 1000us
(XEN) credits per msec = 10
(XEN) ticks per tslice = 3
(XEN) migration delay = 0us
(XEN) idlers: 00000000,00006d29
(XEN) active vcpus:
(XEN) 1: [1.7] pri=-1 flags=0 cpu=15 credit=-116 [w=256,cap=0] (84+300) {a/i=22/21 m=18+5 (k=0)}
(XEN) 2: [1.3] pri=0 flags=0 cpu=1 credit=-113 [w=256,cap=0] (87+300) {a/i=37/36 m=11+544 (k=0)}
(XEN) 3: [0.15] pri=-1 flags=0 cpu=4 credit=95 [w=256,cap=0] (210+300) {a/i=127/126 m=108+9 (k=0)}
(XEN) 4: [0.10] pri=-2 flags=0 cpu=12 credit=-287 [w=256,cap=0] (-84+300) {a/i=163/162 m=36+568 (k=0)}
(XEN) 5: [0.7] pri=-2 flags=0 cpu=2 credit=-242 [w=256,cap=0] (-42+300) {a/i=129/128 m=16+50 (k=0)} (XEN) CPU[00] sort=11801, sibling=00000000,00000003, core=00000000,000000ff
(XEN) run: [32767.0] pri=-64 flags=0 cpu=0
... ... ...
(XEN) CPU[15] sort=11820, sibling=00000000,0000c000, core=00000000,0000ff00
(XEN) run: [1.7] pri=-1 flags=0 cpu=15 credit=-116 [w=256,cap=0] (84+300) {a/i=22/21 m=18+5 (k=0)}
(XEN) 1: [32767.15] pri=-64 flags=0 cpu=15
(XEN) Cpupool 1:
(XEN) Cpus: 6-7,9
(XEN) Scheduler: SMP RTDS Scheduler (rtds)
(XEN) CPU[06]
(XEN) CPU[07]
(XEN) CPU[09]
With this change, we get rid of the redundancy, and retain only the information about the free pCPUs.
(While there, turn a loop index variable from int' to unsigned int' in schedule_dump().)
--- xen/common/cpupool.c | 6 +++--- xen/common/schedule.c | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 8 deletions(-)
xen/common/cpupool.c +3 -3
@@ -728,10 +728,10 @@ void dump_runq(unsigned char key)print_cpumap ("Online Cpus" , &cpu_online_map);if ( !cpumask_empty (&cpupool_free_cpus) ) + {print_cpumap ("Free Cpus" , &cpupool_free_cpus); - -printk ("Idle cpupool:\n" ); -schedule_dump (NULL ); +schedule_dump (NULL ); + }for_each_cpupool (c) {
xen/common/schedule.c +13 -5
@@ -1473,16 +1473,24 @@ void scheduler_free(struct scheduler *sched)void schedule_dump (struct cpupool *c) { -int i; +unsigned int i;struct scheduler *sched;cpumask_t *cpus;/* Locking, if necessary, must be handled withing each scheduler */ - sched = (c ==NULL ) ? &ops : c->sched; - cpus =cpupool_scheduler_cpumask (c); -printk ("Scheduler: %s (%s)\n" , sched->name, sched->opt_name); -SCHED_OP (sched, dump_settings); +if ( c !=NULL ) + { + sched = c->sched; + cpus = c->cpu_valid; +printk ("Scheduler: %s (%s)\n" , sched->name, sched->opt_name); +SCHED_OP (sched, dump_settings); + } +else + { + sched = &ops; + cpus = &cpupool_free_cpus; + } for_each_cpu (i, cpus) {
PATCH v2 2/4 xen: x86 / cpupool: clear the proper cpu_valid bit on pCPU teardown
In reply to Dario FaggioliIn fact, when a pCPU goes down, we want to clear its bit in the correct cpupool's valid mask, rather than always in cpupool0's one.
Before this commit, all the pCPUs in the non-default pool(s) will be considered immediately valid, during system resume, even the one that have not been brought up yet. As a result, the (Credit1) scheduler will attempt to run its load balancing logic on them, causing the following Oops:
# xl cpupool-cpu-remove Pool-0 8-15 # xl cpupool-create name=\"Pool-1\" # xl cpupool-cpu-add Pool-1 8-15 --> suspend --> resume (XEN) ----[ Xen-4.6-unstable x86_64 debug=y Tainted: C ]---- (XEN) CPU: 8 (XEN) RIP: e008:[<ffff82d080123078>] csched_schedule+0x4be/0xb97 (XEN) RFLAGS: 0000000000010087 CONTEXT: hypervisor (XEN) rax: 80007d2f7fccb780 rbx: 0000000000000009 rcx: 0000000000000000 (XEN) rdx: ffff82d08031ed40 rsi: ffff82d080334980 rdi: 0000000000000000 (XEN) rbp: ffff83010000fe20 rsp: ffff83010000fd40 r8: 0000000000000004 (XEN) r9: 0000ffff0000ffff r10: 00ff00ff00ff00ff r11: 0f0f0f0f0f0f0f0f (XEN) r12: ffff8303191ea870 r13: ffff8303226aadf0 r14: 0000000000000009 (XEN) r15: 0000000000000008 cr0: 000000008005003b cr4: 00000000000026f0 (XEN) cr3: 00000000dba9d000 cr2: 0000000000000000 (XEN) ds: 0000 es: 0000 fs: 0000 gs: 0000 ss: 0000 cs: e008 (XEN) ... ... ... (XEN) Xen call trace: (XEN) [<ffff82d080123078>] csched_schedule+0x4be/0xb97 (XEN) [<ffff82d08012c732>] schedule+0x12a/0x63c (XEN) [<ffff82d08012f8c8>] __do_softirq+0x82/0x8d (XEN) [<ffff82d08012f920>] do_softirq+0x13/0x15 (XEN) [<ffff82d080164791>] idle_loop+0x5b/0x6b (XEN) (XEN) **************************************** (XEN) Panic on CPU 8: (XEN) GENERAL PROTECTION FAULT (XEN) [error_code=0000] (XEN) ****************************************
The reason why the error is a #GP fault is that, without this commit, we try to access the per-cpu area of a not yet allocated and initialized pCPU.
In fact, %rax, which is what is used as pointer, is 80007d2f7fccb780, and we also have this:
#define INVALID_PERCPU_AREA (0x8000000000000000L - (long)__per_cpu_start)
---
Cc: Jan Beulich <[email protected]>
Changes from v1:
- improve the changelog, as requested during review.
--- xen/arch/x86/smpboot.c | 1 - xen/common/cpupool.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-)
xen/arch/x86/smpboot.c +0 -1
@@ -887,7 +887,6 @@ void __cpu_disable(void)remove_siblinginfo (cpu);/* It's now safe to remove this processor from the online map */ -cpumask_clear_cpu (cpu, cpupool0->cpu_valid);cpumask_clear_cpu (cpu, &cpu_online_map);fixup_irqs ();
xen/common/cpupool.c +2 -0
@@ -530,6 +530,7 @@ static int cpupool_cpu_remove(unsigned int cpu)if (cpumask_test_cpu (cpu, (*c)->cpu_valid ) ) {cpumask_set_cpu (cpu, (*c)->cpu_suspended); +cpumask_clear_cpu (cpu, (*c)->cpu_valid);break ; } }
@@ -552,6 +553,7 @@ static int cpupool_cpu_remove(unsigned int cpu)* If we are not suspending, we are hot-unplugging cpu, and that is * allowed only for CPUs in pool0. */ +cpumask_clear_cpu (cpu, cpupool0->cpu_valid); ret =0 ; }
PATCH v2 3/4 xen: credit1: properly deal with pCPUs not in any cpupool
In reply to Dario FaggioliIdeally, the pCPUs that are 'free', i.e., not assigned to any cpupool, should not be considred by the scheduler for load balancing or anything. In Credit1, we fail at this, because of how we use cpupool_scheduler_cpumask(). In fact, for a free pCPU, cpupool_scheduler_cpumask() returns a pointer to cpupool_free_cpus, and hence, near the top of csched_load_balance():
if ( unlikely(!cpumask_test_cpu(cpu, online)) )
goto out;
is false (the pCPU _is_ free!), and we therefore do not jump to the end right away, as we should. This, causes the following splat when resuming from ACPI S3 with pCPUs not assigned to any pool:
(XEN) ----[ Xen-4.6-unstable x86_64 debug=y Tainted: C ]----
(XEN) ... ... ...
(XEN) Xen call trace:
(XEN) [<ffff82d080122eaa>] csched_load_balance+0x213/0x794 (XEN) [<ffff82d08012374c>] csched_schedule+0x321/0x452 (XEN) [<ffff82d08012c85e>] schedule+0x12a/0x63c (XEN) [<ffff82d08012fa09>] __do_softirq+0x82/0x8d (XEN) [<ffff82d08012fa61>] do_softirq+0x13/0x15 (XEN) [<ffff82d080164780>] idle_loop+0x5b/0x6b
(XEN)
(XEN)
(XEN) ****************************************
(XEN) Panic on CPU 8:
(XEN) GENERAL PROTECTION FAULT
(XEN) [error_code=0000]
(XEN) ****************************************
The cure is:
* use cpupool_online_cpumask(), as a better guard to the case when the cpu is being offlined;
* explicitly check whether the cpu is free.
SEDF is in a similar situation, so fix it too.
Still in Credit1, we must make sure that free (or offline) CPUs are not considered "ticklable". Not doing so would impair the load balancing algorithm, making the scheduler think that it is possible to 'ask' the pCPU to pick up some work, while in reallity, that will never happen! Evidence of such behavior is shown in this trace:
Name CPU list
Pool-0 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
0.112998198 | ||.|| -|x||-|- d0v0 runstate_change d0v4 offline->runnable
] 0.112998198 | ||.|| -|x||-|- d0v0 22006(2:2:6) 1 [ f ]
] 0.112999612 | ||.|| -|x||-|- d0v0 28004(2:8:4) 2 [ 0 4 ]
0.113003387 | ||.|| -||||-|x d32767v15 runstate_continue d32767v15 running->runningwhere "22006(2:2:6) 1 [ f ]" means that pCPU 15, which is free from any pool, is tickled.
The cure, in this case, is to filter out the free pCPUs, within __runq_tickle().
--- xen/common/sched_credit.c | 23 ++++++++++++++++------- xen/common/sched_sedf.c | 3 ++- 2 files changed, 18 insertions(+), 8 deletions(-)
xen/common/sched_credit.c +16 -7
@@ -366,12 +366,17 @@ __runq_tickle(unsigned int cpu, struct csched_vcpu *new) {struct csched_vcpu *const cur =CSCHED_VCPU (curr_on_cpu (cpu));struct csched_private *prv =CSCHED_PRIV (per_cpu (scheduler, cpu)); -cpumask_t mask, idle_mask; +cpumask_t mask, idle_mask, *online;int balance_step, idlers_empty;ASSERT (cur);cpumask_clear (&mask); - idlers_empty =cpumask_empty (prv->idlers); + +/* cpu is vc->processor, so it must be in a cpupool. */ +ASSERT (per_cpu (cpupool, cpu) !=NULL ); + online =cpupool_online_cpumask (per_cpu (cpupool, cpu)); +cpumask_and (&idle_mask, prv->idlers, online); + idlers_empty =cpumask_empty (&idle_mask);/*
@@ -408,8 +413,8 @@ __runq_tickle(unsigned int cpu, struct csched_vcpu *new)/* Are there idlers suitable for new (for this balance step)? */ csched_balance_cpumask (new->vcpu, balance_step, csched_balance_mask); -cpumask_and (&idle_mask, prv->idlers, csched_balance_mask); - new_idlers_empty =cpumask_empty (&idle_mask); +cpumask_and (csched_balance_mask, csched_balance_mask, &idle_mask); + new_idlers_empty =cpumask_empty (csched_balance_mask);/* * Let's not be too harsh! If there aren't idlers suitable
@@ -1510,6 +1515,7 @@ static struct csched_vcpu * csched_load_balance(struct csched_private *prv, int cpu, struct csched_vcpu *snext, bool_t *stolen) { + struct cpupool *c = per_cpu(cpupool, cpu);struct csched_vcpu *speer;cpumask_t workers;cpumask_t *online;
@@ -1517,10 +1523,13 @@ csched_load_balance(struct csched_private *prv, int cpu,int node =cpu_to_node (cpu);BUG_ON ( cpu != snext->vcpu->processor ); - online =cpupool_scheduler_cpumask (per_cpu (cpupool, cpu)); + online =cpupool_online_cpumask (c); -/* If this CPU is going offline we shouldn't steal work. */ -if (unlikely (!cpumask_test_cpu (cpu, online)) ) +/* +* If this CPU is going offline, or is not (yet) part of any cpupool +* (as it happens, e.g., during cpu bringup), we shouldn't steal work. +*/ +if (unlikely (!cpumask_test_cpu (cpu, online) || c ==NULL ) ) goto out;if ( snext->pri ==CSCHED_PRI_IDLE )
xen/common/sched_sedf.c +2 -1
@@ -790,7 +790,8 @@ static struct task_slice sedf_do_schedule(if ( tasklet_work_scheduled || (list_empty (runq) &&list_empty (waitq)) ||unlikely (!cpumask_test_cpu (cpu, -cpupool_scheduler_cpumask (per_cpu (cpupool, cpu)))) ) +cpupool_online_cpumask (per_cpu (cpupool, cpu))) || +per_cpu (cpupool, cpu) ==NULL ) ) { ret.task =IDLETASK (cpu); ret.time =SECONDS (1 );
PATCH v2 4/4 xen: sched: get rid of cpupool_scheduler_cpumask()
In reply to Dario Faggioliand of (almost every) direct use of cpupool_online_cpumask().
In fact, what we really want for the most of the times, is the set of valid pCPUs of the cpupool a certain domain is part of. Furthermore, in case it's called with a NULL pool as argument, cpupool_scheduler_cpumask() does more harm than good, by returning the bitmask of free pCPUs!
This commit, therefore:
* gets rid of cpupool_scheduler_cpumask(), in favour of cpupool_domain_cpumask(), which makes it more evident what we are after, and accommodates some sanity checking;
* replaces some of the calls to cpupool_online_cpumask() with calls to the new functions too.
---
Cc: George Dunlap <[email protected]>
Changes from v1:
- kill a redundant ASSERT() in __runq_tickle(), as suggested during review (I'll keep the removal of the cpu argumant to that same function for a follow-up patch)
- make cpupool_domain_cpumask() just return d->cpupool->cpu_valid, which is what was happening already, but obfuscated, as requested during review.
--- xen/common/domain.c | 5 +++-- xen/common/domctl.c | 4 ++-- xen/common/sched_arinc653.c | 2 +- xen/common/sched_credit.c | 8 +++----- xen/common/sched_rt.c | 12 ++++++------ xen/common/sched_sedf.c | 2 +- xen/common/schedule.c | 2 +- xen/include/xen/sched-if.h | 12 ++++++++++-- 8 files changed, 27 insertions(+), 20 deletions(-)
xen/common/domain.c +3 -2
@@ -184,7 +184,8 @@ struct vcpu *alloc_vcpu(/* Must be called after making new vcpu visible to for_each_vcpu(). */ vcpu_check_shutdown (v); -domain_update_node_affinity (d); +if ( !is_idle_domain (d) ) +domain_update_node_affinity (d);return v; }
@@ -437,7 +438,7 @@ void domain_update_node_affinity(struct domain *d)return ; } - online =cpupool_online_cpumask (d->cpupool); + online =cpupool_domain_cpumask (d);spin_lock (&d->node_affinity_lock);
xen/common/domctl.c +2 -2
@@ -664,7 +664,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) goto maxvcpu_out; ret = -ENOMEM ; - online =cpupool_online_cpumask (d->cpupool); + online =cpupool_domain_cpumask (d);if ( max > d->max_vcpus ) {struct vcpu **vcpus;
@@ -748,7 +748,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)if ( op->cmd == XEN_DOMCTL_setvcpuaffinity ) {cpumask_var_t new_affinity, old_affinity; -cpumask_t *online =cpupool_online_cpumask (v->domain->cpupool);; +cpumask_t *online =cpupool_domain_cpumask (v->domain);;/* * We want to be able to restore hard affinity if we are trying
xen/common/sched_arinc653.c +1 -1
@@ -667,7 +667,7 @@ a653sched_pick_cpu(const struct scheduler *ops, struct vcpu *vc)* If present, prefer vc's current processor, else * just find the first valid vcpu . */ - online =cpupool_scheduler_cpumask (vc->domain->cpupool); + online =cpupool_domain_cpumask (vc->domain); cpu =cpumask_first (online);
xen/common/sched_credit.c +3 -5
@@ -309,7 +309,7 @@ __runq_remove(struct csched_vcpu *svc)static inline int __vcpu_has_soft_affinity (const struct vcpu *vc,const cpumask_t *mask) { -return !cpumask_subset (cpupool_online_cpumask (vc->domain->cpupool), +return !cpumask_subset (cpupool_domain_cpumask (vc->domain), vc->cpu_soft_affinity) && !cpumask_subset (vc->cpu_hard_affinity, vc->cpu_soft_affinity) &&cpumask_intersects (vc->cpu_soft_affinity, mask);
@@ -372,9 +372,7 @@ __runq_tickle(unsigned int cpu, struct csched_vcpu *new)ASSERT (cur);cpumask_clear (&mask); -/* cpu is vc->processor, so it must be in a cpupool. */ -ASSERT (per_cpu (cpupool, cpu) !=NULL ); - online =cpupool_online_cpumask (per_cpu (cpupool, cpu)); + online =cpupool_domain_cpumask (new->sdom->dom);cpumask_and (&idle_mask, prv->idlers, online); idlers_empty =cpumask_empty (&idle_mask);
@@ -641,7 +639,7 @@ _csched_cpu_pick(const struct scheduler *ops, struct vcpu *vc, bool_t commit)int balance_step;/* Store in cpus the mask of online cpus on which the domain can run */ - online =cpupool_scheduler_cpumask (vc->domain->cpupool); + online =cpupool_domain_cpumask (vc->domain);cpumask_and (&cpus, vc->cpu_hard_affinity, online);for_each_csched_balance_step ( balance_step )
xen/common/sched_rt.c +6 -6
@@ -256,7 +256,7 @@ rt_dump_vcpu(const struct scheduler *ops, const struct rt_vcpu *svc)*/ mask = _cpumask_scratch[svc->vcpu->processor]; - cpupool_mask =cpupool_scheduler_cpumask (svc->vcpu->domain->cpupool); + cpupool_mask =cpupool_domain_cpumask (svc->vcpu->domain);cpumask_and (mask, cpupool_mask, svc->vcpu->cpu_hard_affinity);cpulist_scnprintf (keyhandler_scratch,sizeof (keyhandler_scratch), mask); printk("[%5d.%-2u] cpu %u, (%"PRI_stime", %"PRI_stime"),"
@@ -673,7 +673,7 @@ rt_cpu_pick(const struct scheduler *ops, struct vcpu *vc)cpumask_t *online;int cpu; - online =cpupool_scheduler_cpumask (vc->domain->cpupool); + online =cpupool_domain_cpumask (vc->domain);cpumask_and (&cpus, online, vc->cpu_hard_affinity); cpu =cpumask_test_cpu (vc->processor, &cpus)
@@ -753,7 +753,7 @@ __runq_pick(const struct scheduler *ops, const cpumask_t *mask) iter_svc =__q_elem (iter);/* mask cpu_hard_affinity & cpupool & mask */ - online =cpupool_scheduler_cpumask (iter_svc->vcpu->domain->cpupool); + online =cpupool_domain_cpumask (iter_svc->vcpu->domain);cpumask_and (&cpu_common, online, iter_svc->vcpu->cpu_hard_affinity);cpumask_and (&cpu_common, mask, &cpu_common);if (cpumask_empty (&cpu_common) )
@@ -965,7 +965,7 @@ runq_tickle(const struct scheduler *ops, struct rt_vcpu *new)if ( new ==NULL ||is_idle_vcpu (new->vcpu) )return ; - online =cpupool_scheduler_cpumask (new->vcpu->domain->cpupool); + online =cpupool_domain_cpumask (new->vcpu->domain);cpumask_and (¬_tickled, online, new->vcpu->cpu_hard_affinity);cpumask_andnot (¬_tickled, ¬_tickled, &prv->tickled);
@@ -1078,7 +1078,7 @@ rt_vcpu_wake(const struct scheduler *ops, struct vcpu *vc)ASSERT (!list_empty (&prv->sdom)); sdom = list_entry(prv->sdom.next, struct rt_dom, sdom_elem); - online =cpupool_scheduler_cpumask (sdom->dom->cpupool); + online =cpupool_domain_cpumask (sdom->dom); snext =__runq_pick (ops, online);/* pick snext from ALL valid cpus */ runq_tickle (ops, snext);
@@ -1113,7 +1113,7 @@ rt_context_saved(const struct scheduler *ops, struct vcpu *vc)ASSERT (!list_empty (&prv->sdom)); sdom = list_entry(prv->sdom.next, struct rt_dom, sdom_elem); - online =cpupool_scheduler_cpumask (sdom->dom->cpupool); + online =cpupool_domain_cpumask (sdom->dom); snext =__runq_pick (ops, online);/* pick snext from ALL cpus */ runq_tickle (ops, snext);
xen/common/sched_sedf.c +1 -1
@@ -383,7 +383,7 @@ static int sedf_pick_cpu(const struct scheduler *ops, struct vcpu *v)cpumask_t online_affinity;cpumask_t *online; - online =cpupool_scheduler_cpumask (v->domain->cpupool); + online =cpupool_domain_cpumask (v->domain);cpumask_and (&online_affinity, v->cpu_hard_affinity, online);return cpumask_cycle (v->vcpu_id %cpumask_weight (&online_affinity) -1 , &online_affinity);
xen/common/schedule.c +1 -1
@@ -80,7 +80,7 @@ static struct scheduler __read_mostly ops;#define DOM2OP (_d) (((_d)->cpupool == NULL) ? &ops : ((_d)->cpupool->sched))#define VCPU2OP (_v) (DOM2OP((_v)->domain)) -#define VCPU2ONLINE (_v) cpupool_online_cpumask((_v)->domain->cpupool) +#define VCPU2ONLINE (_v) cpupool_domain_cpumask((_v)->domain)static inline void trace_runstate_change (struct vcpu *v,int new_state) {
xen/include/xen/sched-if.h +10 -2
@@ -183,9 +183,17 @@ 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) +static inline cpumask_t *cpupool_domain_cpumask (struct domain *d) +{ +/* +* d->cpupool is NULL only for the idle domain, and no one should +* be interested in calling this for the idle domain. +*/ +ASSERT (d->cpupool !=NULL ); +return d->cpupool->cpu_valid; +} +#endif /* __XEN_SCHED_IF_H__ */