[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN] Improve scheduler cap mechanism
# HG changeset patch # User Emmanuel Ackaouy <ack@xxxxxxxxxxxxx> # Node ID 360eb996fa38319867a74bf581c734a80bf6839d # Parent c79f9d7882046074d30f58f769aadce5950357d9 [XEN] Improve scheduler cap mechanism Somewhat unbastardize the scheduler cap mechanism. We now cleanly pause and unpause running VCPUs of capped out domains instead of using sub-idle priorities. This also improves the precision of caps a bit. Signed-off-by: Emmanuel Ackaouy <ack@xxxxxxxxxxxxx> --- xen/common/domain.c | 19 +++++++++--- xen/common/sched_credit.c | 71 +++++++++++++++++++++++++++++++++------------- xen/include/xen/sched.h | 1 3 files changed, 67 insertions(+), 24 deletions(-) diff -r c79f9d788204 -r 360eb996fa38 xen/common/domain.c --- a/xen/common/domain.c Wed Dec 13 10:20:20 2006 -0500 +++ b/xen/common/domain.c Wed Dec 13 16:13:26 2006 +0000 @@ -350,16 +350,25 @@ void domain_destroy(struct domain *d) send_guest_global_virq(dom0, VIRQ_DOM_EXC); } -void vcpu_pause(struct vcpu *v) -{ - ASSERT(v != current); - +static void vcpu_pause_setup(struct vcpu *v) +{ spin_lock(&v->pause_lock); if ( v->pause_count++ == 0 ) set_bit(_VCPUF_paused, &v->vcpu_flags); spin_unlock(&v->pause_lock); - +} + +void vcpu_pause(struct vcpu *v) +{ + ASSERT(v != current); + vcpu_pause_setup(v); vcpu_sleep_sync(v); +} + +void vcpu_pause_nosync(struct vcpu *v) +{ + vcpu_pause_setup(v); + vcpu_sleep_nosync(v); } void vcpu_unpause(struct vcpu *v) diff -r c79f9d788204 -r 360eb996fa38 xen/common/sched_credit.c --- a/xen/common/sched_credit.c Wed Dec 13 10:20:20 2006 -0500 +++ b/xen/common/sched_credit.c Wed Dec 13 16:13:26 2006 +0000 @@ -56,7 +56,12 @@ #define CSCHED_PRI_TS_UNDER -1 /* time-share w/ credits */ #define CSCHED_PRI_TS_OVER -2 /* time-share w/o credits */ #define CSCHED_PRI_IDLE -64 /* idle */ -#define CSCHED_PRI_TS_PARKED -65 /* time-share w/ capped credits */ + + +/* + * Flags + */ +#define CSCHED_FLAG_VCPU_PARKED 0x0001 /* VCPU over capped credits */ /* @@ -100,6 +105,8 @@ _MACRO(vcpu_wake_onrunq) \ _MACRO(vcpu_wake_runnable) \ _MACRO(vcpu_wake_not_runnable) \ + _MACRO(vcpu_park) \ + _MACRO(vcpu_unpark) \ _MACRO(tickle_local_idler) \ _MACRO(tickle_local_over) \ _MACRO(tickle_local_under) \ @@ -190,6 +197,7 @@ struct csched_vcpu { struct csched_dom *sdom; struct vcpu *vcpu; atomic_t credit; + uint16_t flags; int16_t pri; #ifdef CSCHED_STATS struct { @@ -579,12 +587,11 @@ csched_vcpu_init(struct vcpu *vc) svc->sdom = sdom; svc->vcpu = vc; atomic_set(&svc->credit, 0); + svc->flags = 0U; svc->pri = is_idle_domain(dom) ? CSCHED_PRI_IDLE : CSCHED_PRI_TS_UNDER; CSCHED_VCPU_STATS_RESET(svc); vc->sched_priv = svc; - CSCHED_VCPU_CHECK(vc); - /* Allocate per-PCPU info */ if ( unlikely(!CSCHED_PCPU(vc->processor)) ) { @@ -593,7 +600,6 @@ csched_vcpu_init(struct vcpu *vc) } CSCHED_VCPU_CHECK(vc); - return 0; } @@ -673,9 +679,16 @@ csched_vcpu_wake(struct vcpu *vc) * This allows wake-to-run latency sensitive VCPUs to preempt * more CPU resource intensive VCPUs without impacting overall * system fairness. - */ - if ( svc->pri == CSCHED_PRI_TS_UNDER ) + * + * The one exception is for VCPUs of capped domains unpausing + * after earning credits they had overspent. We don't boost + * those. + */ + if ( svc->pri == CSCHED_PRI_TS_UNDER && + !(svc->flags & CSCHED_FLAG_VCPU_PARKED) ) + { svc->pri = CSCHED_PRI_TS_BOOST; + } /* Put the VCPU on the runq and tickle CPUs */ __runq_insert(cpu, svc); @@ -749,11 +762,8 @@ static void static void csched_dom_destroy(struct domain *dom) { - struct csched_dom * const sdom = CSCHED_DOM(dom); - CSCHED_STAT_CRANK(dom_destroy); - - xfree(sdom); + xfree(CSCHED_DOM(dom)); } /* @@ -942,11 +952,19 @@ csched_acct(void) */ if ( credit < 0 ) { - if ( sdom->cap != 0U && credit < -credit_cap ) - svc->pri = CSCHED_PRI_TS_PARKED; - else - svc->pri = CSCHED_PRI_TS_OVER; - + svc->pri = CSCHED_PRI_TS_OVER; + + /* Park running VCPUs of capped-out domains */ + if ( sdom->cap != 0U && + credit < -credit_cap && + !(svc->flags & CSCHED_FLAG_VCPU_PARKED) ) + { + CSCHED_STAT_CRANK(vcpu_park); + vcpu_pause_nosync(svc->vcpu); + svc->flags |= CSCHED_FLAG_VCPU_PARKED; + } + + /* Lower bound on credits */ if ( credit < -CSCHED_CREDITS_PER_TSLICE ) { CSCHED_STAT_CRANK(acct_min_credit); @@ -958,6 +976,20 @@ csched_acct(void) { svc->pri = CSCHED_PRI_TS_UNDER; + /* Unpark any capped domains whose credits go positive */ + if ( svc->flags & CSCHED_FLAG_VCPU_PARKED) + { + /* + * It's important to unset the flag AFTER the unpause() + * call to make sure the VCPU's priority is not boosted + * if it is woken up here. + */ + CSCHED_STAT_CRANK(vcpu_unpark); + vcpu_unpause(svc->vcpu); + svc->flags &= ~CSCHED_FLAG_VCPU_PARKED; + } + + /* Upper bound on credits means VCPU stops earning */ if ( credit > CSCHED_CREDITS_PER_TSLICE ) { __csched_vcpu_acct_stop_locked(svc); @@ -1031,10 +1063,10 @@ csched_runq_steal(int peer_cpu, int cpu, speer = __runq_elem(iter); /* - * If next available VCPU here is not of higher priority - * than ours, this PCPU is useless to us. + * If next available VCPU here is not of strictly higher + * priority than ours, this PCPU is useless to us. */ - if ( speer->pri <= CSCHED_PRI_IDLE || speer->pri <= pri ) + if ( speer->pri <= pri ) break; /* Is this VCPU is runnable on our PCPU? */ @@ -1181,10 +1213,11 @@ csched_dump_vcpu(struct csched_vcpu *svc { struct csched_dom * const sdom = svc->sdom; - printk("[%i.%i] pri=%i cpu=%i", + printk("[%i.%i] pri=%i flags=%x cpu=%i", svc->vcpu->domain->domain_id, svc->vcpu->vcpu_id, svc->pri, + svc->flags, svc->vcpu->processor); if ( sdom ) diff -r c79f9d788204 -r 360eb996fa38 xen/include/xen/sched.h --- a/xen/include/xen/sched.h Wed Dec 13 10:20:20 2006 -0500 +++ b/xen/include/xen/sched.h Wed Dec 13 16:13:26 2006 +0000 @@ -437,6 +437,7 @@ static inline int vcpu_runnable(struct v } void vcpu_pause(struct vcpu *v); +void vcpu_pause_nosync(struct vcpu *v); void domain_pause(struct domain *d); void vcpu_unpause(struct vcpu *v); void domain_unpause(struct domain *d); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |