[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH] x86/S3: Fix cpu pool scheduling after suspend/resume (v3)



This had the wrong description text pasted from my last patch submission last 
week. 

Apologies. 

The code is sound. 

On Apr 17, 2013, at 5:16 PM, "Ben Guthro" <Ben.Guthro@xxxxxxxxxx> wrote:

> This review is another S3 scheduler problem with the system_state variable 
> introduced with the following changeset:
> http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=269f543ea750ed567d18f2e819e5d5ce58eda5c5
> 
> Specifically, the cpu_callback function that takes the CPU down during 
> suspend, and back up during resume.
> We were seeing situations where, after S3, only CPU0 was in cpupool0. Guest 
> performance suffered greatly, since all vcpus were only on a single pcpu. 
> Guests under high CPU load showed the problem much more quickly than an idle 
> guest.
> 
> Removing this if condition forces the CPUs to go through the expected 
> online/offline state, and be properly scheduled after S3.
> 
> This also includes a necessary partial change proposed earlier by Tomasz 
> Wroblewski here:
> http://lists.xen.org/archives/html/xen-devel/2013-01/msg02206.html
> 
> It should also resolve the issues discussed in this thread:
> http://lists.xen.org/archives/html/xen-devel/2012-11/msg01801.html
> 
> v2:
> Address concerns from Juergen Gross about the cpus not being put back into 
> the pool they were in prior to suspend
> 
> v3:
> Addressed leak of cpu_suspended, clean up hard tabs
> 
> Signed-off-by: Ben Guthro <benjamin.guthro@xxxxxxxxxx>
> ---
> xen/common/cpupool.c       |   57 ++++++++++++++++++++++++++++++++++----------
> xen/include/xen/sched-if.h |    1 +
> 2 files changed, 46 insertions(+), 12 deletions(-)
> 
> diff --git a/xen/common/cpupool.c b/xen/common/cpupool.c
> index 10b10f8..6b5a3db 100644
> --- a/xen/common/cpupool.c
> +++ b/xen/common/cpupool.c
> @@ -40,17 +40,31 @@ DEFINE_PER_CPU(struct cpupool *, cpupool);
> static struct cpupool *alloc_cpupool_struct(void)
> {
>     struct cpupool *c = xzalloc(struct cpupool);
> +    if ( !c )
> +        return NULL;
> 
> -    if ( c && zalloc_cpumask_var(&c->cpu_valid) )
> -        return c;
> -    xfree(c);
> -    return NULL;
> +    if ( !zalloc_cpumask_var(&c->cpu_suspended) )
> +    {
> +        xfree(c);
> +        return NULL;
> +    }
> +
> +    if ( !zalloc_cpumask_var(&c->cpu_valid) )
> +    {
> +        free_cpumask_var(c->cpu_suspended);
> +        xfree(c);
> +        return NULL;
> +    }
> +
> +    return c;
> }
> 
> static void free_cpupool_struct(struct cpupool *c)
> {
> -    if ( c )
> +    if ( c ) {
> +        free_cpumask_var(c->cpu_suspended);
>         free_cpumask_var(c->cpu_valid);
> +    }
>     xfree(c);
> }
> 
> @@ -417,14 +431,32 @@ void cpupool_rm_domain(struct domain *d)
> 
> /*
>  * called to add a new cpu to pool admin
> - * we add a hotplugged cpu to the cpupool0 to be able to add it to dom0
> + * we add a hotplugged cpu to the cpupool0 to be able to add it to dom0,
> + * unless we are resuming from S3, in which case we put the cpu back
> + * in the cpupool it was in prior to suspend.
>  */
> static void cpupool_cpu_add(unsigned int cpu)
> {
> +    struct cpupool **c;
>     spin_lock(&cpupool_lock);
> +
>     cpumask_clear_cpu(cpu, &cpupool_locked_cpus);
>     cpumask_set_cpu(cpu, &cpupool_free_cpus);
> -    cpupool_assign_cpu_locked(cpupool0, cpu);
> +
> +    if ( system_state == SYS_STATE_resume )
> +    {
> +        for_each_cpupool(c)
> +        {
> +            if ( cpumask_test_cpu(cpu, (*c)->cpu_suspended ) )
> +            {
> +                cpupool_assign_cpu_locked((*c), cpu);
> +                cpumask_clear_cpu(cpu, (*c)->cpu_suspended);
> +            }
> +        }
> +    }
> +
> +    if ( cpumask_test_cpu(cpu, &cpupool_free_cpus) )
> +        cpupool_assign_cpu_locked(cpupool0, cpu);
>     spin_unlock(&cpupool_lock);
> }
> 
> @@ -436,7 +468,7 @@ static void cpupool_cpu_add(unsigned int cpu)
> static int cpupool_cpu_remove(unsigned int cpu)
> {
>     int ret = 0;
> -    
> +
>     spin_lock(&cpupool_lock);
>     if ( !cpumask_test_cpu(cpu, cpupool0->cpu_valid))
>         ret = -EBUSY;
> @@ -630,12 +662,14 @@ void dump_runq(unsigned char key)
> static int cpu_callback(
>     struct notifier_block *nfb, unsigned long action, void *hcpu)
> {
> +    struct cpupool **c;
>     unsigned int cpu = (unsigned long)hcpu;
>     int rc = 0;
> 
> -    if ( (system_state == SYS_STATE_suspend) ||
> -         (system_state == SYS_STATE_resume) )
> -        goto out;
> +    if ( system_state == SYS_STATE_suspend )
> +        for_each_cpupool(c)
> +            if ( cpumask_test_cpu(cpu, (*c)->cpu_valid ) )
> +                cpumask_set_cpu(cpu, (*c)->cpu_suspended);
> 
>     switch ( action )
>     {
> @@ -650,7 +684,6 @@ static int cpu_callback(
>         break;
>     }
> 
> -out:
>     return !rc ? NOTIFY_DONE : notifier_from_errno(rc);
> }
> 
> diff --git a/xen/include/xen/sched-if.h b/xen/include/xen/sched-if.h
> index 9ace22c..84bb13f 100644
> --- a/xen/include/xen/sched-if.h
> +++ b/xen/include/xen/sched-if.h
> @@ -201,6 +201,7 @@ struct cpupool
> {
>     int              cpupool_id;
>     cpumask_var_t    cpu_valid;      /* all cpus assigned to pool */
> +    cpumask_var_t    cpu_suspended;  /* cpus in S3 that should be in this 
> pool */
>     struct cpupool   *next;
>     unsigned int     n_dom;
>     struct scheduler *sched;
> -- 
> 1.7.9.5
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.