[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)



On Apr 19, 2013, at 5:40 AM, Jürgen Groß <juergen.gross@xxxxxxxxxxxxxx> wrote:

> Am 17.04.2013 23:16, schrieb Ben Guthro:
>> 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>
> 
> Not tested, as I'm on vacation, but looks okay, so:
> 
> Acked-by: Juergen Gross <juergen.gross@xxxxxxxxxxxxxx>
> 

Thanks for the review Jürgen.

Jan - is this a candidate for commit to 4.3, or will this be pushed out because 
of the code freeze?



>> ---
>>  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;
>> 
> 


_______________________________________________
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®.