|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 1/2] xen: credit2: implement yield()
On 30/09/16 15:21, Dario Faggioli wrote:
> When a vcpu explicitly yields it is usually giving
> us an advice of "let someone else run and come back
> to me in a bit."
>
> Credit2 isn't, so far, doing anything when a vcpu
> yields, which means an yield is basically a NOP (well,
> actually, it's pure overhead, as it causes the scheduler
> kick in, but the result is --at least 99% of the time--
> that the very same vcpu that yielded continues to run).
>
> With this patch, when a vcpu yields, we go and try
> picking the next vcpu on the runqueue that can run on
> the pcpu where the yielding vcpu is running. Of course,
> if we don't find any other vcpu that wants and can run
> there, the yielding vcpu will continue.
>
> Also, add an yield performance counter, and fix the
> style of a couple of comments.
>
> Signed-off-by: Dario Faggioli <dario.faggioli@xxxxxxxxxx>
Thanks!
Reviewed-by: George Dunlap <george.dunlap@xxxxxxxxxx>
> ---
> Cc: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
> Cc: Anshul Makkar <anshul.makkar@xxxxxxxxxx>
> Cc: Jan Beulich <jbeulich@xxxxxxxx>
> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
> ---
> Changes from v2:
> * implement yield as a "switch", rather than as a "knob", as suggested
> during review.
>
> Changes from v1:
> * add _us to the parameter name, as suggested during review;
> * get rid of the minimum value for the yield bias;
> * apply the idle bias via subtraction of credits to the yielding vcpu, rather
> than via addition to all the others;
> * merge the Credit2 bits of what was patch 7 here, as suggested during
> review.
> ---
> xen/common/sched_credit2.c | 54
> +++++++++++++++++++++++++++++++-----------
> xen/common/schedule.c | 2 ++
> xen/include/xen/perfc_defn.h | 1 +
> 3 files changed, 43 insertions(+), 14 deletions(-)
>
> diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c
> index 72e31b5..c0646e9 100644
> --- a/xen/common/sched_credit2.c
> +++ b/xen/common/sched_credit2.c
> @@ -181,7 +181,13 @@
> */
> #define __CSFLAG_runq_migrate_request 3
> #define CSFLAG_runq_migrate_request (1<<__CSFLAG_runq_migrate_request)
> -
> +/*
> + * CSFLAG_vcpu_yield: this vcpu was running, and has called vcpu_yield(). The
> + * scheduler is invoked to see if we can give the cpu to someone else, and
> + * get back to the yielding vcpu in a while.
> + */
> +#define __CSFLAG_vcpu_yield 4
> +#define CSFLAG_vcpu_yield (1<<__CSFLAG_vcpu_yield)
>
> static unsigned int __read_mostly opt_migrate_resist = 500;
> integer_param("sched_credit2_migrate_resist", opt_migrate_resist);
> @@ -1431,6 +1437,14 @@ out:
> }
>
> static void
> +csched2_vcpu_yield(const struct scheduler *ops, struct vcpu *v)
> +{
> + struct csched2_vcpu * const svc = CSCHED2_VCPU(v);
> +
> + __set_bit(__CSFLAG_vcpu_yield, &svc->flags);
> +}
> +
> +static void
> csched2_context_saved(const struct scheduler *ops, struct vcpu *vc)
> {
> struct csched2_vcpu * const svc = CSCHED2_VCPU(vc);
> @@ -2250,26 +2264,31 @@ runq_candidate(struct csched2_runqueue_data *rqd,
> struct list_head *iter;
> struct csched2_vcpu *snext = NULL;
> struct csched2_private *prv = CSCHED2_PRIV(per_cpu(scheduler, cpu));
> + bool yield = __test_and_clear_bit(__CSFLAG_vcpu_yield, &scurr->flags);
>
> *skipped = 0;
>
> - /* Default to current if runnable, idle otherwise */
> - if ( vcpu_runnable(scurr->vcpu) )
> - snext = scurr;
> - else
> - snext = CSCHED2_VCPU(idle_vcpu[cpu]);
> -
> /*
> * Return the current vcpu if it has executed for less than ratelimit.
> * Adjuststment for the selected vcpu's credit and decision
> * for how long it will run will be taken in csched2_runtime.
> + *
> + * Note that, if scurr is yielding, we don't let rate limiting kick in.
> + * In fact, it may be the case that scurr is about to spin, and there's
> + * no point forcing it to do so until rate limiting expires.
> */
> - if ( prv->ratelimit_us && !is_idle_vcpu(scurr->vcpu) &&
> + if ( !yield && prv->ratelimit_us && !is_idle_vcpu(scurr->vcpu) &&
> vcpu_runnable(scurr->vcpu) &&
> (now - scurr->vcpu->runstate.state_entry_time) <
> MICROSECS(prv->ratelimit_us) )
> return scurr;
>
> + /* Default to current if runnable, idle otherwise */
> + if ( vcpu_runnable(scurr->vcpu) )
> + snext = scurr;
> + else
> + snext = CSCHED2_VCPU(idle_vcpu[cpu]);
> +
> list_for_each( iter, &rqd->runq )
> {
> struct csched2_vcpu * svc = list_entry(iter, struct csched2_vcpu,
> runq_elem);
> @@ -2293,8 +2312,10 @@ runq_candidate(struct csched2_runqueue_data *rqd,
> continue;
> }
>
> - /* If this is on a different processor, don't pull it unless
> - * its credit is at least CSCHED2_MIGRATE_RESIST higher. */
> + /*
> + * If this is on a different processor, don't pull it unless
> + * its credit is at least CSCHED2_MIGRATE_RESIST higher.
> + */
> if ( svc->vcpu->processor != cpu
> && snext->credit + CSCHED2_MIGRATE_RESIST > svc->credit )
> {
> @@ -2303,9 +2324,12 @@ runq_candidate(struct csched2_runqueue_data *rqd,
> continue;
> }
>
> - /* If the next one on the list has more credit than current
> - * (or idle, if current is not runnable), choose it. */
> - if ( svc->credit > snext->credit )
> + /*
> + * If the next one on the list has more credit than current
> + * (or idle, if current is not runnable), or if current is
> + * yielding, choose it.
> + */
> + if ( yield || svc->credit > snext->credit )
> snext = svc;
>
> /* In any case, if we got this far, break. */
> @@ -2391,7 +2415,8 @@ csched2_schedule(
> */
> if ( tasklet_work_scheduled )
> {
> - trace_var(TRC_CSCHED2_SCHED_TASKLET, 1, 0, NULL);
> + __clear_bit(__CSFLAG_vcpu_yield, &scurr->flags);
> + trace_var(TRC_CSCHED2_SCHED_TASKLET, 1, 0, NULL);
> snext = CSCHED2_VCPU(idle_vcpu[cpu]);
> }
> else
> @@ -2975,6 +3000,7 @@ static const struct scheduler sched_credit2_def = {
>
> .sleep = csched2_vcpu_sleep,
> .wake = csched2_vcpu_wake,
> + .yield = csched2_vcpu_yield,
>
> .adjust = csched2_dom_cntl,
> .adjust_global = csched2_sys_cntl,
> diff --git a/xen/common/schedule.c b/xen/common/schedule.c
> index 104d203..5b444c4 100644
> --- a/xen/common/schedule.c
> +++ b/xen/common/schedule.c
> @@ -947,6 +947,8 @@ long vcpu_yield(void)
> SCHED_OP(VCPU2OP(v), yield, v);
> vcpu_schedule_unlock_irq(lock, v);
>
> + SCHED_STAT_CRANK(vcpu_yield);
> +
> TRACE_2D(TRC_SCHED_YIELD, current->domain->domain_id, current->vcpu_id);
> raise_softirq(SCHEDULE_SOFTIRQ);
> return 0;
> diff --git a/xen/include/xen/perfc_defn.h b/xen/include/xen/perfc_defn.h
> index 4a835b8..900fddd 100644
> --- a/xen/include/xen/perfc_defn.h
> +++ b/xen/include/xen/perfc_defn.h
> @@ -23,6 +23,7 @@ PERFCOUNTER(vcpu_alloc, "sched: vcpu_alloc")
> PERFCOUNTER(vcpu_insert, "sched: vcpu_insert")
> PERFCOUNTER(vcpu_remove, "sched: vcpu_remove")
> PERFCOUNTER(vcpu_sleep, "sched: vcpu_sleep")
> +PERFCOUNTER(vcpu_yield, "sched: vcpu_yield")
> PERFCOUNTER(vcpu_wake_running, "sched: vcpu_wake_running")
> PERFCOUNTER(vcpu_wake_onrunq, "sched: vcpu_wake_onrunq")
> PERFCOUNTER(vcpu_wake_runnable, "sched: vcpu_wake_runnable")
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |