|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |