[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 2/2] xen/sched: don't disable scheduler on cpus during suspend
On 16/03/2019 04:01, Dario Faggioli wrote: > On Thu, 2019-03-14 at 10:59 +0100, Juergen Gross wrote: >> Today there is special handling in cpu_disable_scheduler() for >> suspend >> by forcing all vcpus to the boot cpu. In fact there is no need for >> that >> as during resume the vcpus are put on the correct cpus again. >> > So, basically, you're saying that moving the vcpus to BSP / CPU0, > before suspending is not necessary, right? Right. > I thought it was, because going into suspend involves things like > cpu_schedule_down(), which does, among other things, > SCHED_OP(free_pdata) for freeing the scheduler's data structs, and > hence we did not want vcpus "around". Suspend is done from a tasklet with all domains "frozen". So there is no active vcpu other than the idle ones in the system, meaning that there is no vcpu in any runqueue. > >> So we can just omit the call of cpu_disable_scheduler() when >> offlining >> a cpu due to suspend and on resuming we can omit taking the schedule >> lock for selecting the new processor. >> > Well, in theory, we should hold the lock when for using > 'cpumask_scratch_cpu(cpu)'. Not sure this is an actual problem in this > case, but still... I think there is no problem as there is no scheduling activity. >> In restore_vcpu_affinity() we should be careful when applying >> affinity >> as the cpu might not have come back to life. >> > But restore_vcpu_affinity() is done, in a loop, for all vcpus of all > domains, in thaw_domains(), which in turn comes after > enable_nonboot_cpus(), which I think is supposed to bring every CPU > back up.... What am I missing? There is no guarantee all cpus will be up after suspend. Some might fail coming up. > >> diff --git a/xen/common/cpupool.c b/xen/common/cpupool.c >> index e89bb67e71..7b5ce18426 100644 >> --- a/xen/common/cpupool.c >> +++ b/xen/common/cpupool.c >> @@ -313,7 +313,7 @@ static long cpupool_unassign_cpu_helper(void >> *info) >> * cpu_disable_scheduler(), and at the bottom of this function. >> */ >> rcu_read_lock(&domlist_read_lock); >> - ret = cpu_disable_scheduler(cpu); >> + ret = (system_state == SYS_STATE_suspend) ? 0 : >> cpu_disable_scheduler(cpu); >> > Mmm... How can this function be called with state = STATE_suspend ? Meh, my bad. I masked the wrong call of cpu_disable_scheduler(). Should have been that from __cpu_disable(). > >> @@ -735,31 +708,36 @@ void restore_vcpu_affinity(struct domain *d) >> >> ASSERT(!vcpu_runnable(v)); >> >> - lock = vcpu_schedule_lock_irq(v); >> - >> - if ( v->affinity_broken ) >> - { >> - sched_set_affinity(v, v->cpu_hard_affinity_saved, NULL); >> - v->affinity_broken = 0; >> - >> - } >> - >> /* >> - * During suspend (in cpu_disable_scheduler()), we moved >> every vCPU >> - * to BSP (which, as of now, is pCPU 0), as a temporary >> measure to >> - * allow the nonboot processors to have their data structure >> freed >> - * and go to sleep. But nothing guardantees that the BSP is >> a valid >> - * pCPU for a particular domain. >> + * Re-assign the initial processor as after resume we have >> no >> + * guarantee the old processor has come back to life again. >> * >> * Therefore, here, before actually unpausing the domains, >> we should >> * set v->processor of each of their vCPUs to something that >> will >> * make sense for the scheduler of the cpupool in which they >> are in. >> */ >> cpumask_and(cpumask_scratch_cpu(cpu), v->cpu_hard_affinity, >> - cpupool_domain_cpumask(v->domain)); >> - v->processor = cpumask_any(cpumask_scratch_cpu(cpu)); >> + cpupool_domain_cpumask(d)); >> + if ( cpumask_empty(cpumask_scratch_cpu(cpu)) ) >> + { >> + if ( v->affinity_broken ) >> + { >> + sched_set_affinity(v, v->cpu_hard_affinity_saved, >> NULL); >> + v->affinity_broken = 0; >> + cpumask_and(cpumask_scratch_cpu(cpu), v- >>> cpu_hard_affinity, >> + cpupool_domain_cpumask(d)); >> + } >> > I'm not sure I follow this; I'll think deeper, but, in the meanwhile... > >> - spin_unlock_irq(lock); >> + if ( cpumask_empty(cpumask_scratch_cpu(cpu)) ) >> + { >> + printk(XENLOG_DEBUG "Breaking affinity for %pv\n", >> v); >> + sched_set_affinity(v, &cpumask_all, NULL); >> + cpumask_and(cpumask_scratch_cpu(cpu), v- >>> cpu_hard_affinity, >> + cpupool_domain_cpumask(d)); >> > ... what does it mean we're breaking the affinity while trying to > restore it? > > When/where is this vcpu getting its real affinity back in place then? This is only happening in case a cpu didn't come up again. There is no way to restore the real affinity in this case. Juergen _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |