[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC][PATCH 4/4] sched: introduce boost credit for latency-sensitive domain
I attached the following two patches. credit_rev2_4_boost_xen.patch : modification to xen hypervisor credit_rev2_4_boost_tools.patch: modification to tools By applying these two patches, boost credit is introduced to the credit scheduler. The credit scheduler comes to be able to give priority to latency-sensitive domain. The differences between these patches and last patches are as follows.- When a vcpu is waked up and set to BOOST state, add CSCHED_CREDITS_PER_TICK to boost_credit and subtract CSCHED_CREDITS_PER_TICK from credit. This prevents the vcpu from returning to UNDER state immediately. Especially dom0 is affected largely. - Even if the vcpu has boost credit, if current tims slice is 2ms then don't send scheduler interrupt. - If credit of a vcpu is subtracted over CSCHED_CREDITS_PER_TSLICE, adjust the credit. Best regards, Naoki Nishiguchi diff -r 8bc795246b5b xen/common/sched_credit.c --- a/xen/common/sched_credit.c Wed Dec 17 16:02:47 2008 +0900 +++ b/xen/common/sched_credit.c Wed Dec 17 16:04:43 2008 +0900 @@ -47,6 +47,7 @@ (CSCHED_CREDITS_PER_TICK * CSCHED_TICKS_PER_TSLICE) #define CSCHED_CREDITS_PER_ACCT \ (CSCHED_CREDITS_PER_TICK * CSCHED_TICKS_PER_ACCT) +#define CSCHED_MSECS_PER_BOOST_TSLICE 2 /* @@ -189,6 +190,7 @@ struct csched_pcpu { struct timer ticker; unsigned int tick; s_time_t start_time; + s_time_t time_slice; }; /* @@ -201,6 +203,8 @@ struct csched_vcpu { struct csched_dom *sdom; struct vcpu *vcpu; atomic_t credit; + atomic_t boost_credit; + int prev_credit; uint16_t flags; int16_t pri; #ifdef CSCHED_STATS @@ -225,6 +229,8 @@ struct csched_dom { uint16_t active_vcpu_count; uint16_t weight; uint16_t cap; + uint16_t boost_ratio; + uint16_t max_boost_period; }; /* @@ -239,8 +245,11 @@ struct csched_private { cpumask_t idlers; uint32_t weight; uint32_t credit; + uint32_t boost_credit; + uint16_t total_boost_ratio; int credit_balance; uint32_t runq_sort; + s_time_t boost_tslice; CSCHED_STATS_DEFINE() }; @@ -250,6 +259,10 @@ struct csched_private { */ static struct csched_private csched_priv; +/* opt_credit_tslice: time slice for BOOST priority */ +static unsigned int opt_credit_tslice = CSCHED_MSECS_PER_BOOST_TSLICE; +integer_param("credit_tslice", opt_credit_tslice); + static void csched_tick(void *_cpu); static inline int @@ -304,6 +317,7 @@ __runq_tickle(unsigned int cpu, struct c { struct csched_vcpu * const cur = CSCHED_VCPU(per_cpu(schedule_data, cpu).curr); + struct csched_pcpu * const spc = CSCHED_PCPU(cpu); cpumask_t mask; ASSERT(cur); @@ -340,6 +354,16 @@ __runq_tickle(unsigned int cpu, struct c cpus_or(mask, mask, csched_priv.idlers); cpus_and(mask, mask, new->vcpu->cpu_affinity); } + } + + /* If new VCPU has boost credit, signal the CPU. */ + if ( cpus_empty(mask) && + new->pri == CSCHED_PRI_TS_BOOST && + spc->time_slice != csched_priv.boost_tslice && + new->sdom->max_boost_period ) + { + CSCHED_STAT_CRANK(tickle_local_other); + cpu_set(cpu, mask); } /* Send scheduler interrupts to designated CPUs */ @@ -503,6 +527,8 @@ __csched_vcpu_acct_start_locked(struct c { list_add(&sdom->active_sdom_elem, &csched_priv.active_sdom); csched_priv.weight += sdom->weight; + csched_priv.boost_credit += (sdom->boost_ratio * + CSCHED_CREDITS_PER_TSLICE) / 100; } } } @@ -525,6 +551,8 @@ __csched_vcpu_acct_stop_locked(struct cs BUG_ON( csched_priv.weight < sdom->weight ); list_del_init(&sdom->active_sdom_elem); csched_priv.weight -= sdom->weight; + csched_priv.boost_credit -= (sdom->boost_ratio * + CSCHED_CREDITS_PER_TSLICE) / 100; } } @@ -535,14 +563,6 @@ csched_vcpu_acct(unsigned int cpu) ASSERT( current->processor == cpu ); ASSERT( svc->sdom != NULL ); - - /* - * If this VCPU's priority was boosted when it last awoke, reset it. - * If the VCPU is found here, then it's consuming a non-negligeable - * amount of CPU resources and should no longer be boosted. - */ - if ( svc->pri == CSCHED_PRI_TS_BOOST ) - svc->pri = CSCHED_PRI_TS_UNDER; /* * If it's been active a while, check if we'd be better off @@ -579,6 +599,8 @@ csched_vcpu_init(struct vcpu *vc) svc->sdom = sdom; svc->vcpu = vc; atomic_set(&svc->credit, 0); + atomic_set(&svc->boost_credit, 0); + svc->prev_credit = 0; svc->flags = 0U; svc->pri = is_idle_domain(dom) ? CSCHED_PRI_IDLE : CSCHED_PRI_TS_UNDER; CSCHED_VCPU_STATS_RESET(svc); @@ -693,6 +715,8 @@ csched_vcpu_wake(struct vcpu *vc) !(svc->flags & CSCHED_FLAG_VCPU_PARKED) ) { svc->pri = CSCHED_PRI_TS_BOOST; + atomic_add(CSCHED_CREDITS_PER_TICK, &svc->boost_credit); + atomic_sub(CSCHED_CREDITS_PER_TICK, &svc->credit); } /* Put the VCPU on the runq and tickle CPUs */ @@ -712,25 +736,73 @@ csched_dom_cntl( { op->u.credit.weight = sdom->weight; op->u.credit.cap = sdom->cap; + op->u.credit.max_boost_period = sdom->max_boost_period; + op->u.credit.boost_ratio = sdom->boost_ratio; } else { + uint16_t weight = (uint16_t)~0U; + ASSERT(op->cmd == XEN_DOMCTL_SCHEDOP_putinfo); spin_lock_irqsave(&csched_priv.lock, flags); - if ( op->u.credit.weight != 0 ) + if ( (op->u.credit.weight != 0) && + (sdom->boost_ratio == 0 || op->u.credit.boost_ratio == 0) ) + { + weight = op->u.credit.weight; + } + + if ( op->u.credit.cap != (uint16_t)~0U ) + sdom->cap = op->u.credit.cap; + + if ( (op->u.credit.max_boost_period != (uint16_t)~0U) && + (op->u.credit.max_boost_period >= CSCHED_MSECS_PER_TICK || + op->u.credit.max_boost_period == 0) ) + { + sdom->max_boost_period = op->u.credit.max_boost_period; + } + + if ( (op->u.credit.boost_ratio != (uint16_t)~0U) && + ((csched_priv.total_boost_ratio - sdom->boost_ratio + + op->u.credit.boost_ratio) <= 100 * csched_priv.ncpus) && + (sdom->max_boost_period || op->u.credit.boost_ratio == 0) ) + { + uint16_t new_bc, old_bc; + + new_bc = (op->u.credit.boost_ratio * + CSCHED_CREDITS_PER_TSLICE) / 100; + old_bc = (sdom->boost_ratio * + CSCHED_CREDITS_PER_TSLICE) / 100; + + csched_priv.total_boost_ratio -= sdom->boost_ratio; + csched_priv.total_boost_ratio += op->u.credit.boost_ratio; + + sdom->boost_ratio = op->u.credit.boost_ratio; + + if ( !list_empty(&sdom->active_sdom_elem) ) + { + csched_priv.boost_credit -= old_bc; + csched_priv.boost_credit += new_bc; + } + if ( new_bc == 0 ) + { + if ( sdom->weight == 0 ) + weight = CSCHED_DEFAULT_WEIGHT; + } + else + weight = 0; + } + + if ( weight != (uint16_t)~0U ) { if ( !list_empty(&sdom->active_sdom_elem) ) { csched_priv.weight -= sdom->weight; - csched_priv.weight += op->u.credit.weight; + csched_priv.weight += weight; } - sdom->weight = op->u.credit.weight; - } - - if ( op->u.credit.cap != (uint16_t)~0U ) - sdom->cap = op->u.credit.cap; + sdom->weight = weight; + } spin_unlock_irqrestore(&csched_priv.lock, flags); } @@ -759,6 +831,8 @@ csched_dom_init(struct domain *dom) sdom->dom = dom; sdom->weight = CSCHED_DEFAULT_WEIGHT; sdom->cap = 0U; + sdom->boost_ratio = 0U; + sdom->max_boost_period = 0U; dom->sched_priv = sdom; return 0; @@ -774,15 +848,16 @@ csched_dom_destroy(struct domain *dom) /* * This is a O(n) optimized sort of the runq. * - * Time-share VCPUs can only be one of two priorities, UNDER or OVER. We walk - * through the runq and move up any UNDERs that are preceded by OVERS. We - * remember the last UNDER to make the move up operation O(1). + * Time-share VCPUs can only be one of three priorities, BOOST, UNDER or OVER. + * We walk through the runq and move up any BOOSTs that are preceded by UNDERs + * or OVERs, and any UNDERs that are preceded by OVERS. We remember the last + * BOOST and UNDER to make the move up operation O(1). */ static void csched_runq_sort(unsigned int cpu) { struct csched_pcpu * const spc = CSCHED_PCPU(cpu); - struct list_head *runq, *elem, *next, *last_under; + struct list_head *runq, *elem, *next, *last_boost, *last_under; struct csched_vcpu *svc_elem; unsigned long flags; int sort_epoch; @@ -797,14 +872,26 @@ csched_runq_sort(unsigned int cpu) runq = &spc->runq; elem = runq->next; - last_under = runq; + last_boost = last_under = runq; while ( elem != runq ) { next = elem->next; svc_elem = __runq_elem(elem); - if ( svc_elem->pri >= CSCHED_PRI_TS_UNDER ) + if ( svc_elem->pri == CSCHED_PRI_TS_BOOST ) + { + /* does elem need to move up the runq? */ + if ( elem->prev != last_boost ) + { + list_del(elem); + list_add(elem, last_boost); + } + if ( last_boost == last_under ) + last_under = elem; + last_boost = elem; + } + else if ( svc_elem->pri == CSCHED_PRI_TS_UNDER ) { /* does elem need to move up the runq? */ if ( elem->prev != last_under ) @@ -840,6 +927,14 @@ csched_acct(void) int credit; int64_t credit_sum; int credit_average; + /* for boost credit */ + uint32_t bc_total; + uint32_t bc_fair; + int boost_credit; + int max_boost_credit; + int64_t bc_sum; + int bc_average; + spin_lock_irqsave(&csched_priv.lock, flags); @@ -848,8 +943,12 @@ csched_acct(void) { svc = list_entry(iter_vcpu, struct csched_vcpu, inactive_vcpu_elem); - if ( atomic_read(&svc->credit) - <= CSCHED_CREDITS_PER_TICK * (CSCHED_TICKS_PER_ACCT - 1) ) + max_boost_credit = svc->sdom->max_boost_period * + (CSCHED_CREDITS_PER_TSLICE/CSCHED_MSECS_PER_TSLICE); + if ( (atomic_read(&svc->credit) + <= CSCHED_CREDITS_PER_TICK * (CSCHED_TICKS_PER_ACCT - 1)) || + (atomic_read(&svc->boost_credit) + <= (max_boost_credit - CSCHED_CREDITS_PER_TICK)) ) { __csched_vcpu_acct_start_locked(svc); } @@ -857,6 +956,7 @@ csched_acct(void) weight_total = csched_priv.weight; credit_total = csched_priv.credit; + bc_total = csched_priv.boost_credit; /* Converge balance towards 0 when it drops negative */ if ( csched_priv.credit_balance < 0 ) @@ -865,7 +965,7 @@ csched_acct(void) CSCHED_STAT_CRANK(acct_balance); } - if ( unlikely(weight_total == 0) ) + if ( unlikely(weight_total == 0 && bc_total == 0) ) { csched_priv.credit_balance = 0; spin_unlock_irqrestore(&csched_priv.lock, flags); @@ -880,26 +980,59 @@ csched_acct(void) credit_xtra = 0; credit_cap = 0U; + /* Firstly, subtract boost credits from credit_total. */ + if ( bc_total != 0 ) + { + credit_total -= bc_total; + credit_balance += bc_total; + } + + /* Avoid 0 divide error */ + if ( weight_total == 0 ) + weight_total = 1; + list_for_each_safe( iter_sdom, next_sdom, &csched_priv.active_sdom ) { sdom = list_entry(iter_sdom, struct csched_dom, active_sdom_elem); BUG_ON( is_idle_domain(sdom->dom) ); BUG_ON( sdom->active_vcpu_count == 0 ); - BUG_ON( sdom->weight == 0 ); BUG_ON( sdom->weight > weight_left ); - /* Compute the average of active VCPUs. */ + max_boost_credit = sdom->max_boost_period * + (CSCHED_CREDITS_PER_TSLICE / CSCHED_MSECS_PER_TSLICE); + + /* + * Compute the average of active VCPUs + * and adjust credit for comsumption too much. + */ credit_sum = 0; + bc_sum = 0; list_for_each_safe( iter_vcpu, next_vcpu, &sdom->active_vcpu ) { + int adjust; + svc = list_entry(iter_vcpu, struct csched_vcpu, active_vcpu_elem); BUG_ON( sdom != svc->sdom ); + credit = atomic_read(&svc->credit); + boost_credit = atomic_read(&svc->boost_credit); + adjust = svc->prev_credit - (credit + boost_credit) + - CSCHED_CREDITS_PER_TSLICE; + if ( adjust > 0 ) + { + if ( max_boost_credit != 0 ) + atomic_add(adjust, &svc->boost_credit); + else + atomic_add(adjust, &svc->credit); + } credit_sum += atomic_read(&svc->credit); + bc_sum += atomic_read(&svc->boost_credit); } credit_average = ( credit_sum + (sdom->active_vcpu_count - 1) ) / sdom->active_vcpu_count; + bc_average = ( bc_sum + (sdom->active_vcpu_count - 1) + ) / sdom->active_vcpu_count; weight_left -= sdom->weight; @@ -934,7 +1067,9 @@ csched_acct(void) if ( credit_fair < credit_peak ) { - credit_xtra = 1; + /* credit_fair is 0 if weight is 0. */ + if ( sdom->weight != 0 ) + credit_xtra = 1; } else { @@ -966,6 +1101,10 @@ csched_acct(void) credit_fair = ( credit_fair + ( sdom->active_vcpu_count - 1 ) ) / sdom->active_vcpu_count; + /* Compute fair share of boost credit per VCPU */ + bc_fair = ( ((sdom->boost_ratio * CSCHED_CREDITS_PER_ACCT)/100) + + (sdom->active_vcpu_count - 1) + ) / sdom->active_vcpu_count; list_for_each_safe( iter_vcpu, next_vcpu, &sdom->active_vcpu ) { @@ -976,6 +1115,54 @@ csched_acct(void) credit = atomic_read(&svc->credit); atomic_add(credit_average - credit + credit_fair, &svc->credit); credit = atomic_read(&svc->credit); + + /* Balance and increment boost credit */ + boost_credit = atomic_read(&svc->boost_credit); + atomic_add(bc_average - boost_credit + bc_fair, &svc->boost_credit); + boost_credit = atomic_read(&svc->boost_credit); + + /* + * Upper bound on credits. + * Add excess to boost credit. + */ + if ( credit > CSCHED_CREDITS_PER_TSLICE ) + { + atomic_add(credit - CSCHED_CREDITS_PER_TSLICE, + &svc->boost_credit); + boost_credit = atomic_read(&svc->boost_credit); + credit = CSCHED_CREDITS_PER_TSLICE; + atomic_set(&svc->credit, credit); + } + /* + * Upper bound on boost credits. + * Add excess to credit. + */ + if ( boost_credit > max_boost_credit ) + { + atomic_add(boost_credit - max_boost_credit, &svc->credit); + credit = atomic_read(&svc->credit); + boost_credit = max_boost_credit; + atomic_set(&svc->boost_credit, boost_credit); + } + /* + * If credit is negative, + * boost credits compensate credit. + */ + if ( credit < 0 && boost_credit > 0 ) + { + if ( boost_credit > -credit ) + { + atomic_sub(-credit, &svc->boost_credit); + atomic_add(-credit, &svc->credit); + } + else + { + atomic_sub(boost_credit, &svc->boost_credit); + atomic_add(boost_credit, &svc->credit); + } + credit = atomic_read(&svc->credit); + boost_credit = atomic_read(&svc->boost_credit); + } /* * Recompute priority or, if VCPU is idling, remove it from @@ -1005,7 +1192,10 @@ csched_acct(void) } else { - svc->pri = CSCHED_PRI_TS_UNDER; + if ( boost_credit > 0 ) + svc->pri = CSCHED_PRI_TS_BOOST; + else + svc->pri = CSCHED_PRI_TS_UNDER; /* Unpark any capped domains whose credits go positive */ if ( svc->flags & CSCHED_FLAG_VCPU_PARKED) @@ -1020,18 +1210,36 @@ csched_acct(void) svc->flags &= ~CSCHED_FLAG_VCPU_PARKED; } - /* Upper bound on credits means VCPU stops earning */ + /* + * Upper bound on credits and boost credits means VCPU stops + * earning + */ if ( credit > CSCHED_CREDITS_PER_TSLICE ) { - __csched_vcpu_acct_stop_locked(svc); credit = CSCHED_CREDITS_PER_TSLICE; atomic_set(&svc->credit, credit); + + if ( boost_credit >= max_boost_credit ) + { + __csched_vcpu_acct_stop_locked(svc); + } } } - CSCHED_VCPU_STAT_SET(svc, credit_last, credit); - CSCHED_VCPU_STAT_SET(svc, credit_incr, credit_fair); - credit_balance += credit; + /* save credit for adjustment */ + svc->prev_credit = credit + boost_credit; + + if ( sdom->boost_ratio == 0 ) + { + CSCHED_VCPU_STAT_SET(svc, credit_last, credit); + CSCHED_VCPU_STAT_SET(svc, credit_incr, credit_fair); + credit_balance += credit; + } + else + { + CSCHED_VCPU_STAT_SET(svc, credit_last, boost_credit); + CSCHED_VCPU_STAT_SET(svc, credit_incr, bc_fair); + } } } @@ -1216,6 +1424,22 @@ csched_schedule(s_time_t now) ) / ( MILLISECS(CSCHED_MSECS_PER_TSLICE) / CSCHED_CREDITS_PER_TSLICE ); + if ( scurr->pri == CSCHED_PRI_TS_BOOST ) + { + int boost_credit = atomic_read(&scurr->boost_credit); + + if ( boost_credit > consumed ) + { + atomic_sub(consumed, &scurr->boost_credit); + consumed = 0; + } + else + { + atomic_sub(boost_credit, &scurr->boost_credit); + consumed -= boost_credit; + scurr->pri = CSCHED_PRI_TS_UNDER; + } + } if ( consumed > 0 && !is_idle_vcpu(current) ) atomic_sub(consumed, &scurr->credit); @@ -1259,9 +1483,20 @@ csched_schedule(s_time_t now) /* * Return task to run next... */ - ret.time = MILLISECS(CSCHED_MSECS_PER_TSLICE); + if ( snext->pri == CSCHED_PRI_TS_BOOST ) + { + struct csched_vcpu * const svc = __runq_elem(runq->next); + + if ( svc->pri == CSCHED_PRI_TS_BOOST ) + ret.time = csched_priv.boost_tslice; + else + ret.time = MILLISECS(CSCHED_MSECS_PER_TICK); + } + else + ret.time = MILLISECS(CSCHED_MSECS_PER_TSLICE); ret.task = snext->vcpu; + spc->time_slice = ret.time; spc->start_time = now; CSCHED_VCPU_CHECK(ret.task); @@ -1282,7 +1517,11 @@ csched_dump_vcpu(struct csched_vcpu *svc if ( sdom ) { - printk(" credit=%i [w=%u]", atomic_read(&svc->credit), sdom->weight); + printk(" credit=%i bc=%i [w=%u,bc=%i]", + atomic_read(&svc->credit), + atomic_read(&svc->boost_credit), + sdom->weight, + (sdom->boost_ratio * CSCHED_CREDITS_PER_TSLICE)/100); #ifdef CSCHED_STATS printk(" (%d+%u) {a/i=%u/%u m=%u+%u}", svc->stats.credit_last, @@ -1348,6 +1587,8 @@ csched_dump(void) "\tcredit balance = %d\n" "\tweight = %u\n" "\trunq_sort = %u\n" + "\tboost_credit = %u\n" + "\ttotal_boost_ratio = %u\n" "\tdefault-weight = %d\n" "\tmsecs per tick = %dms\n" "\tcredits per tick = %d\n" @@ -1359,6 +1600,8 @@ csched_dump(void) csched_priv.credit_balance, csched_priv.weight, csched_priv.runq_sort, + csched_priv.boost_credit, + csched_priv.total_boost_ratio, CSCHED_DEFAULT_WEIGHT, CSCHED_MSECS_PER_TICK, CSCHED_CREDITS_PER_TICK, @@ -1412,6 +1655,9 @@ csched_init(void) csched_priv.credit = 0U; csched_priv.credit_balance = 0; csched_priv.runq_sort = 0U; + csched_priv.boost_credit = 0; + csched_priv.total_boost_ratio = 0; + csched_priv.boost_tslice = MILLISECS(opt_credit_tslice); CSCHED_STATS_RESET(); } diff -r 8bc795246b5b xen/include/public/domctl.h --- a/xen/include/public/domctl.h Wed Dec 17 16:02:47 2008 +0900 +++ b/xen/include/public/domctl.h Wed Dec 17 16:04:43 2008 +0900 @@ -311,6 +311,8 @@ struct xen_domctl_scheduler_op { struct xen_domctl_sched_credit { uint16_t weight; uint16_t cap; + uint16_t max_boost_period; + uint16_t boost_ratio; } credit; } u; }; diff -r 9dfd98cac0cc tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Wed Dec 17 16:05:11 2008 +0900 +++ b/tools/python/xen/lowlevel/xc/xc.c Wed Dec 17 16:05:42 2008 +0900 @@ -1284,18 +1284,26 @@ static PyObject *pyxc_sched_credit_domai uint32_t domid; uint16_t weight; uint16_t cap; - static char *kwd_list[] = { "domid", "weight", "cap", NULL }; - static char kwd_type[] = "I|HH"; + uint16_t max_boost_period; + uint16_t boost_ratio; + static char *kwd_list[] = { "domid", "weight", "cap", + "max_boost_period", "boost_ratio", NULL }; + static char kwd_type[] = "I|HHhh"; struct xen_domctl_sched_credit sdom; weight = 0; cap = (uint16_t)~0U; + max_boost_period = (uint16_t)~0U; + boost_ratio = (uint16_t)~0U; if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list, - &domid, &weight, &cap) ) + &domid, &weight, &cap, + &max_boost_period, &boost_ratio) ) return NULL; sdom.weight = weight; sdom.cap = cap; + sdom.max_boost_period = max_boost_period; + sdom.boost_ratio = boost_ratio; if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 ) return pyxc_error_to_exception(); @@ -1315,9 +1323,11 @@ static PyObject *pyxc_sched_credit_domai if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 ) return pyxc_error_to_exception(); - return Py_BuildValue("{s:H,s:H}", - "weight", sdom.weight, - "cap", sdom.cap); + return Py_BuildValue("{s:H,s:H,s:i,s:i}", + "weight", sdom.weight, + "cap", sdom.cap, + "max_boost_period", sdom.max_boost_period, + "boost_ratio", sdom.boost_ratio); } static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args) @@ -1723,8 +1733,11 @@ static PyMethodDef pyxc_methods[] = { METH_KEYWORDS, "\n" "Set the scheduling parameters for a domain when running with the\n" "SMP credit scheduler.\n" - " domid [int]: domain id to set\n" - " weight [short]: domain's scheduling weight\n" + " domid [int]: domain id to set\n" + " weight [short]: domain's scheduling weight\n" + " cap [short]: cap\n" + " max_boost_period [short]: upper limit in BOOST priority\n" + " boost_ratio [short]; domain's boost ratio per a cpu\n" "Returns: [int] 0 on success; -1 on error.\n" }, { "sched_credit_domain_get", @@ -1732,9 +1745,12 @@ static PyMethodDef pyxc_methods[] = { METH_VARARGS, "\n" "Get the scheduling parameters for a domain when running with the\n" "SMP credit scheduler.\n" - " domid [int]: domain id to get\n" + " domid [int]: domain id to get\n" "Returns: [dict]\n" - " weight [short]: domain's scheduling weight\n"}, + " weight [short]: domain's scheduling weight\n" + " cap [short]: cap\n" + " max_boost_period [short]: upper limit in BOOST priority\n" + " boost_ratio [short]: domain's boost ratio per a cpu\n"}, { "evtchn_alloc_unbound", (PyCFunction)pyxc_evtchn_alloc_unbound, diff -r 9dfd98cac0cc tools/python/xen/xend/XendAPI.py --- a/tools/python/xen/xend/XendAPI.py Wed Dec 17 16:05:11 2008 +0900 +++ b/tools/python/xen/xend/XendAPI.py Wed Dec 17 16:05:42 2008 +0900 @@ -1505,10 +1505,14 @@ class XendAPI(object): #need to update sched params aswell if 'weight' in xeninfo.info['vcpus_params'] \ - and 'cap' in xeninfo.info['vcpus_params']: + and 'cap' in xeninfo.info['vcpus_params'] \ + and 'max_boost_period' in xeninfo.info['vcpus_params'] \ + and 'boost_ratio' in xeninfo.info['vcpus_params']: weight = xeninfo.info['vcpus_params']['weight'] cap = xeninfo.info['vcpus_params']['cap'] - xendom.domain_sched_credit_set(xeninfo.getDomid(), weight, cap) + max_boost_period = xeninfo.info['vcpus_params']['max_boost_period'] + boost_ratio = xeninfo.info['vcpus_params']['boost_ratio'] + xendom.domain_sched_credit_set(xeninfo.getDomid(), weight, cap, max_boost_period, boost_ratio) def VM_set_VCPUs_number_live(self, _, vm_ref, num): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) diff -r 9dfd98cac0cc tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Wed Dec 17 16:05:11 2008 +0900 +++ b/tools/python/xen/xend/XendConfig.py Wed Dec 17 16:05:42 2008 +0900 @@ -589,6 +589,10 @@ class XendConfig(dict): int(sxp.child_value(sxp_cfg, "cpu_weight", 256)) cfg["vcpus_params"]["cap"] = \ int(sxp.child_value(sxp_cfg, "cpu_cap", 0)) + cfg["vcpus_params"]["max_boost_period"] = \ + int(sxp.child_value(sxp_cfg, "cpu_max_boost_period", 0)) + cfg["vcpus_params"]["boost_ratio"] = \ + int(sxp.child_value(sxp_cfg, "cpu_boost_ratio", 0)) # Only extract options we know about. extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG + \ diff -r 9dfd98cac0cc tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Wed Dec 17 16:05:11 2008 +0900 +++ b/tools/python/xen/xend/XendDomain.py Wed Dec 17 16:05:42 2008 +0900 @@ -1536,7 +1536,7 @@ class XendDomain: @param domid: Domain ID or Name @type domid: int or string. - @rtype: dict with keys 'weight' and 'cap' + @rtype: dict with keys 'weight' and 'cap' and 'max_boost_period' and 'boost_ratio' @return: credit scheduler parameters """ dominfo = self.domain_lookup_nr(domid) @@ -1549,20 +1549,26 @@ class XendDomain: except Exception, ex: raise XendError(str(ex)) else: - return {'weight' : dominfo.getWeight(), - 'cap' : dominfo.getCap()} + return {'weight' : dominfo.getWeight(), + 'cap' : dominfo.getCap(), + 'max_boost_period': dominfo.getMaxBoostPeriod(), + 'boost_ratio' : dominfo.getBoostRatio()} - def domain_sched_credit_set(self, domid, weight = None, cap = None): + def domain_sched_credit_set(self, domid, weight = None, cap = None, max_boost_period = None, boost_ratio = None): """Set credit scheduler parameters for a domain. @param domid: Domain ID or Name @type domid: int or string. @type weight: int @type cap: int + @type max_boost_period: int + @type boost_ratio: int @rtype: 0 """ set_weight = False set_cap = False + set_max_boost_period = False + set_boost_ratio = False dominfo = self.domain_lookup_nr(domid) if not dominfo: raise XendInvalidDomain(str(domid)) @@ -1581,17 +1587,37 @@ class XendDomain: else: set_cap = True + if max_boost_period is None: + max_boost_period = int(~0) + elif max_boost_period < 0: + raise XendError("max_boost_period is out of range") + else: + set_max_boost_period = True + + if boost_ratio is None: + boost_ratio = int(~0) + elif boost_ratio < 0: + raise XendError("boost_ratio is out of range") + else: + set_boost_ratio = True + assert type(weight) == int assert type(cap) == int + assert type(max_boost_period) == int + assert type(boost_ratio) == int rc = 0 if dominfo._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED): - rc = xc.sched_credit_domain_set(dominfo.getDomid(), weight, cap) + rc = xc.sched_credit_domain_set(dominfo.getDomid(), weight, cap, max_boost_period, boost_ratio) if rc == 0: if set_weight: dominfo.setWeight(weight) if set_cap: dominfo.setCap(cap) + if set_max_boost_period: + dominfo.setMaxBoostPeriod(max_boost_period) + if set_boost_ratio: + dominfo.setBoostRatio(boost_ratio) self.managed_config_save(dominfo) return rc except Exception, ex: diff -r 9dfd98cac0cc tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Dec 17 16:05:11 2008 +0900 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Dec 17 16:05:42 2008 +0900 @@ -465,7 +465,9 @@ class XendDomainInfo: if xennode.xenschedinfo() == 'credit': xendomains.domain_sched_credit_set(self.getDomid(), self.getWeight(), - self.getCap()) + self.getCap(), + self.getMaxBoostPeriod(), + self.getBoostRatio()) except: log.exception('VM start failed') self.destroy() @@ -1618,6 +1620,18 @@ class XendDomainInfo: def setWeight(self, cpu_weight): self.info['vcpus_params']['weight'] = cpu_weight + def getMaxBoostPeriod(self): + return self.info['vcpus_params']['max_boost_period'] + + def setMaxBoostPeriod(self, cpu_max_boost_period): + self.info['vcpus_params']['max_boost_period'] = cpu_max_boost_period + + def getBoostRatio(self): + return self.info['vcpus_params']['boost_ratio'] + + def setBoostRatio(self, cpu_boost_ratio): + self.info['vcpus_params']['boost_ratio'] = cpu_boost_ratio + def getRestartCount(self): return self._readVm('xend/restart_count') diff -r 9dfd98cac0cc tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Wed Dec 17 16:05:11 2008 +0900 +++ b/tools/python/xen/xm/main.py Wed Dec 17 16:05:42 2008 +0900 @@ -150,7 +150,7 @@ SUBCOMMAND_HELP = { 'log' : ('', 'Print Xend log'), 'rename' : ('<Domain> <NewDomainName>', 'Rename a domain.'), 'sched-sedf' : ('<Domain> [options]', 'Get/set EDF parameters.'), - 'sched-credit': ('[-d <Domain> [-w[=WEIGHT]|-c[=CAP]]]', + 'sched-credit': ('[-d <Domain> [-w[=WEIGHT]|-c[=CAP]|-m[=MAXBOOSTPERIOD]|-r[=BOOSTRATIO]]]', 'Get/set credit scheduler parameters.'), 'sysrq' : ('<Domain> <letter>', 'Send a sysrq to a domain.'), 'debug-keys' : ('<Keys>', 'Send debug keys to Xen.'), @@ -240,6 +240,8 @@ SUBCOMMAND_OPTIONS = { ('-d DOMAIN', '--domain=DOMAIN', 'Domain to modify'), ('-w WEIGHT', '--weight=WEIGHT', 'Weight (int)'), ('-c CAP', '--cap=CAP', 'Cap (int)'), + ('-m MAXBOOSTPERIOD', '--maxboostperiod=MAXBOOSTPERIOD', 'Upper limit of boost period (ms)'), + ('-r BOOSTRATIO', '--ratio=BOOSTRATIO', 'Boost ratio per a cpu (int)'), ), 'list': ( ('-l', '--long', 'Output all VM details in SXP'), @@ -1578,8 +1580,8 @@ def xm_sched_credit(args): check_sched_type('credit') try: - opts, params = getopt.getopt(args, "d:w:c:", - ["domain=", "weight=", "cap="]) + opts, params = getopt.getopt(args, "d:w:c:m:r:", + ["domain=", "weight=", "cap=", "maxboostperiod=", "ratio="]) except getopt.GetoptError, opterr: err(opterr) usage('sched-credit') @@ -1587,6 +1589,8 @@ def xm_sched_credit(args): domid = None weight = None cap = None + max_boost_period = None + boost_ratio = None for o, a in opts: if o in ["-d", "--domain"]: @@ -1594,18 +1598,22 @@ def xm_sched_credit(args): elif o in ["-w", "--weight"]: weight = int(a) elif o in ["-c", "--cap"]: - cap = int(a); + cap = int(a) + elif o in ["-m", "--maxboostperiod"]: + max_boost_period = int(a) + elif o in ["-r", "--ratio"]: + boost_ratio = int(a); doms = filter(lambda x : domid_match(domid, x), [parse_doms_info(dom) for dom in getDomains(None, 'all')]) - if weight is None and cap is None: + if weight is None and cap is None and max_boost_period is None and boost_ratio is None: if domid is not None and doms == []: err("Domain '%s' does not exist." % domid) usage('sched-credit') # print header if we aren't setting any parameters - print '%-33s %4s %6s %4s' % ('Name','ID','Weight','Cap') + print '%-33s %4s %6s %4s %8s %5s' % ('Name','ID','Weight','Cap','Max(ms)','Ratio') for d in doms: try: @@ -1618,16 +1626,18 @@ def xm_sched_credit(args): except xmlrpclib.Fault: pass - if 'weight' not in info or 'cap' not in info: + if 'weight' not in info or 'cap' not in info or 'max_boost_period' not in info or 'boost_ratio' not in info: # domain does not support sched-credit? - info = {'weight': -1, 'cap': -1} + info = {'weight': -1, 'cap': -1, 'max_boost_period':-1, 'boost_ratio':-1} info['weight'] = int(info['weight']) info['cap'] = int(info['cap']) + info['max_boost_period'] = int(info['max_boost_period']) + info['boost_ratio'] = int(info['boost_ratio']) info['name'] = d['name'] info['domid'] = str(d['domid']) - print( ("%(name)-32s %(domid)5s %(weight)6d %(cap)4d") % info) + print( ("%(name)-32s %(domid)5s %(weight)6d %(cap)4d %(max_boost_period)8d %(boost_ratio)5d") % info) else: if domid is None: # place holder for system-wide scheduler parameters @@ -1644,6 +1654,14 @@ def xm_sched_credit(args): get_single_vm(domid), "cap", cap) + server.xenapi.VM.add_to_VCPUs_params_live( + get_single_vm(domid), + "max_boost_period", + max_boost_period) + server.xenapi.VM.add_to_VCPUs_params_live( + get_single_vm(domid), + "boost_ratio", + boost_ratio) else: server.xenapi.VM.add_to_VCPUs_params( get_single_vm(domid), @@ -1653,8 +1671,16 @@ def xm_sched_credit(args): get_single_vm(domid), "cap", cap) + server.xenapi.VM.add_to_VCPUs_params( + get_single_vm(domid), + "max_boost_period", + max_boost_period) + server.xenapi.VM.add_to_VCPUs_params( + get_single_vm(domid), + "boost_ratio", + boost_ratio) else: - result = server.xend.domain.sched_credit_set(domid, weight, cap) + result = server.xend.domain.sched_credit_set(domid, weight, cap, max_boost_period, boost_ratio) if result != 0: err(str(result)) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |