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

Re: [Xen-devel] [PATCH RESEND 1/4] xen: sched: introduce 'adjust_affinity' hook.



On 03/15/2018 06:35 PM, Dario Faggioli wrote:
> From: Dario Faggioli <raistlin@xxxxxxxx>
> 
> For now, just as a way to give a scheduler an "heads up",
> about the fact that the affinity changed.
> 
> This enables some optimizations, such as pre-computing
> and storing (e.g., in flags) facts like a vcpu being
> exclusively pinned to a pcpu, or having or not a
> soft affinity. I.e., conditions that, despite the fact
> that they rarely change, are right now checked very
> frequently, even in hot paths.
> 
> Note that, as we expect many scheduler specific
> implementations of the adjust_affinity hook to do
> something with the per-scheduler vCPU private data,
> this commit moves the calls to sched_set_affinity()
> after that is allocated (in sched_init_vcpu()).
> 
> Note also that this, in future, may turn out as a useful
> mean for, e.g., having the schedulers vet, ack or nack
> the changes themselves.
> 
> Signed-off-by: Dario Faggioli <raistlin@xxxxxxxx>

Reviewed-by: George Dunlap <george.dunlap@xxxxxxxxxx>

As I said, I can change all these on check-in.

 -George

> ---
> Cc: George Dunlap <george.dunlap@xxxxxxxxxx>
> Cc: Anshul Makkar <anshulmakkar@xxxxxxxxx>
> ---
> Changes from last posting:
> - rebased on staging.
> 
> Changes from v2:
> - fix sched_set_affinity() not to use always hard_affinity;
> - move calls to sched_set_affinity() below per-scheduler vCPU data allocation.
> ---
>  xen/arch/x86/dom0_build.c  |    7 ++--
>  xen/common/schedule.c      |   75 
> ++++++++++++++++++++++++++++++++------------
>  xen/include/xen/sched-if.h |    3 ++
>  xen/include/xen/sched.h    |    3 ++
>  4 files changed, 63 insertions(+), 25 deletions(-)
> 
> diff --git a/xen/arch/x86/dom0_build.c b/xen/arch/x86/dom0_build.c
> index 555660b853..b744791c38 100644
> --- a/xen/arch/x86/dom0_build.c
> +++ b/xen/arch/x86/dom0_build.c
> @@ -140,14 +140,13 @@ struct vcpu *__init dom0_setup_vcpu(struct domain *d,
>      {
>          if ( pv_shim )
>          {
> -            __cpumask_set_cpu(vcpu_id, v->cpu_hard_affinity);
> -            __cpumask_set_cpu(vcpu_id, v->cpu_soft_affinity);
> +            sched_set_affinity(v, cpumask_of(vcpu_id), cpumask_of(vcpu_id));
>          }
>          else
>          {
>              if ( !d->is_pinned && !dom0_affinity_relaxed )
> -                cpumask_copy(v->cpu_hard_affinity, &dom0_cpus);
> -            cpumask_copy(v->cpu_soft_affinity, &dom0_cpus);
> +                sched_set_affinity(v, &dom0_cpus, NULL);
> +            sched_set_affinity(v, NULL, &dom0_cpus);
>          }
>      }
>  
> diff --git a/xen/common/schedule.c b/xen/common/schedule.c
> index 64524f4da7..f43d943765 100644
> --- a/xen/common/schedule.c
> +++ b/xen/common/schedule.c
> @@ -256,18 +256,11 @@ static void sched_spin_unlock_double(spinlock_t *lock1, 
> spinlock_t *lock2,
>  int sched_init_vcpu(struct vcpu *v, unsigned int processor) 
>  {
>      struct domain *d = v->domain;
> +    cpumask_t allcpus;
>  
> -    /*
> -     * Initialize processor and affinity settings. The idler, and potentially
> -     * domain-0 VCPUs, are pinned onto their respective physical CPUs.
> -     */
> -    v->processor = processor;
> -    if ( is_idle_domain(d) || d->is_pinned )
> -        cpumask_copy(v->cpu_hard_affinity, cpumask_of(processor));
> -    else
> -        cpumask_setall(v->cpu_hard_affinity);
> +    cpumask_setall(&allcpus);
>  
> -    cpumask_setall(v->cpu_soft_affinity);
> +    v->processor = processor;
>  
>      /* Initialise the per-vcpu timers. */
>      init_timer(&v->periodic_timer, vcpu_periodic_timer_fn,
> @@ -282,6 +275,15 @@ int sched_init_vcpu(struct vcpu *v, unsigned int 
> processor)
>      if ( v->sched_priv == NULL )
>          return 1;
>  
> +    /*
> +     * Initialize affinity settings. The idler, and potentially
> +     * domain-0 VCPUs, are pinned onto their respective physical CPUs.
> +     */
> +    if ( is_idle_domain(d) || d->is_pinned )
> +        sched_set_affinity(v, cpumask_of(processor), &allcpus);
> +    else
> +        sched_set_affinity(v, &allcpus, &allcpus);
> +
>      /* Idle VCPUs are scheduled immediately, so don't put them in runqueue. 
> */
>      if ( is_idle_domain(d) )
>      {
> @@ -359,6 +361,7 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
>      for_each_vcpu ( d, v )
>      {
>          spinlock_t *lock;
> +        cpumask_t allcpus;
>  
>          vcpudata = v->sched_priv;
>  
> @@ -366,10 +369,12 @@ int sched_move_domain(struct domain *d, struct cpupool 
> *c)
>          migrate_timer(&v->singleshot_timer, new_p);
>          migrate_timer(&v->poll_timer, new_p);
>  
> -        cpumask_setall(v->cpu_hard_affinity);
> -        cpumask_setall(v->cpu_soft_affinity);
> +        cpumask_setall(&allcpus);
>  
>          lock = vcpu_schedule_lock_irq(v);
> +
> +        sched_set_affinity(v, &allcpus, &allcpus);
> +
>          v->processor = new_p;
>          /*
>           * With v->processor modified we must not
> @@ -694,7 +699,7 @@ void restore_vcpu_affinity(struct domain *d)
>  
>          if ( v->affinity_broken )
>          {
> -            cpumask_copy(v->cpu_hard_affinity, v->cpu_hard_affinity_saved);
> +            sched_set_affinity(v, v->cpu_hard_affinity_saved, NULL);
>              v->affinity_broken = 0;
>  
>          }
> @@ -758,6 +763,8 @@ int cpu_disable_scheduler(unsigned int cpu)
>              if ( cpumask_empty(&online_affinity) &&
>                   cpumask_test_cpu(cpu, v->cpu_hard_affinity) )
>              {
> +                cpumask_t allcpus;
> +
>                  if ( v->affinity_broken )
>                  {
>                      /* The vcpu is temporarily pinned, can't move it. */
> @@ -775,7 +782,8 @@ int cpu_disable_scheduler(unsigned int cpu)
>                  else
>                      printk(XENLOG_DEBUG "Breaking affinity for %pv\n", v);
>  
> -                cpumask_setall(v->cpu_hard_affinity);
> +                cpumask_setall(&allcpus);
> +                sched_set_affinity(v, &allcpus, NULL);
>              }
>  
>              if ( v->processor != cpu )
> @@ -845,8 +853,26 @@ int cpu_disable_scheduler(unsigned int cpu)
>      return ret;
>  }
>  
> +/*
> + * In general, this must be called with the scheduler lock held, because the
> + * adjust_affinity hook may want to modify the vCPU state. However, when the
> + * vCPU is being initialized (either for dom0 or domU) there is no risk of
> + * races, and it's fine to not take the look (we're talking about
> + * dom0_setup_vcpu() an sched_init_vcpu()).
> + */
> +void sched_set_affinity(
> +    struct vcpu *v, const cpumask_t *hard, const cpumask_t *soft)
> +{
> +    SCHED_OP(dom_scheduler(v->domain), adjust_affinity, v, hard, soft);
> +
> +    if ( hard )
> +        cpumask_copy(v->cpu_hard_affinity, hard);
> +    if ( soft )
> +        cpumask_copy(v->cpu_soft_affinity, soft);
> +}
> +
>  static int vcpu_set_affinity(
> -    struct vcpu *v, const cpumask_t *affinity, cpumask_t *which)
> +    struct vcpu *v, const cpumask_t *affinity, const cpumask_t *which)
>  {
>      spinlock_t *lock;
>      int ret = 0;
> @@ -857,12 +883,19 @@ static int vcpu_set_affinity(
>          ret = -EBUSY;
>      else
>      {
> -        cpumask_copy(which, affinity);
> -
>          /*
> -         * Always ask the scheduler to re-evaluate placement
> -         * when changing the affinity.
> +         * Tell the scheduler we changes something about affinity,
> +         * and ask to re-evaluate vcpu placement.
>           */
> +        if ( which == v->cpu_hard_affinity )
> +        {
> +            sched_set_affinity(v, affinity, NULL);
> +        }
> +        else
> +        {
> +            ASSERT(which == v->cpu_soft_affinity);
> +            sched_set_affinity(v, NULL, affinity);
> +        }
>          set_bit(_VPF_migrating, &v->pause_flags);
>      }
>  
> @@ -1100,7 +1133,7 @@ int vcpu_pin_override(struct vcpu *v, int cpu)
>      {
>          if ( v->affinity_broken )
>          {
> -            cpumask_copy(v->cpu_hard_affinity, v->cpu_hard_affinity_saved);
> +            sched_set_affinity(v, v->cpu_hard_affinity_saved, NULL);
>              v->affinity_broken = 0;
>              set_bit(_VPF_migrating, &v->pause_flags);
>              ret = 0;
> @@ -1114,7 +1147,7 @@ int vcpu_pin_override(struct vcpu *v, int cpu)
>          {
>              cpumask_copy(v->cpu_hard_affinity_saved, v->cpu_hard_affinity);
>              v->affinity_broken = 1;
> -            cpumask_copy(v->cpu_hard_affinity, cpumask_of(cpu));
> +            sched_set_affinity(v, cpumask_of(cpu), NULL);
>              set_bit(_VPF_migrating, &v->pause_flags);
>              ret = 0;
>          }
> diff --git a/xen/include/xen/sched-if.h b/xen/include/xen/sched-if.h
> index c5dd43ed9c..926d063ccf 100644
> --- a/xen/include/xen/sched-if.h
> +++ b/xen/include/xen/sched-if.h
> @@ -173,6 +173,9 @@ struct scheduler {
>                                      unsigned int);
>      int          (*adjust)         (const struct scheduler *, struct domain 
> *,
>                                      struct xen_domctl_scheduler_op *);
> +    void         (*adjust_affinity)(const struct scheduler *, struct vcpu *,
> +                                    const struct cpumask *,
> +                                    const struct cpumask *);
>      int          (*adjust_global)  (const struct scheduler *,
>                                      struct xen_sysctl_scheduler_op *);
>      void         (*dump_settings)  (const struct scheduler *);
> diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
> index 39f938644a..ade4d7b9aa 100644
> --- a/xen/include/xen/sched.h
> +++ b/xen/include/xen/sched.h
> @@ -846,6 +846,9 @@ void scheduler_free(struct scheduler *sched);
>  int schedule_cpu_switch(unsigned int cpu, struct cpupool *c);
>  void vcpu_force_reschedule(struct vcpu *v);
>  int cpu_disable_scheduler(unsigned int cpu);
> +/* We need it in dom0_setup_vcpu */
> +void sched_set_affinity(struct vcpu *v, const cpumask_t *hard,
> +                        const cpumask_t *soft);
>  int vcpu_set_hard_affinity(struct vcpu *v, const cpumask_t *affinity);
>  int vcpu_set_soft_affinity(struct vcpu *v, const cpumask_t *affinity);
>  void restore_vcpu_affinity(struct domain *d);
> 


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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