From mboxrd@z Thu Jan 1 00:00:00 1970 From: NISHIGUCHI Naoki Subject: Re: [RFC][PATCH] scheduler: credit scheduler for client virtualization Date: Thu, 22 Jan 2009 15:15:53 +0900 Message-ID: <49780F19.1020701@jp.fujitsu.com> References: <49364960.2060101@jp.fujitsu.com> <49768FDB.60609@jp.fujitsu.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------060301020202010505000402" Return-path: In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: George Dunlap Cc: "xen-devel@lists.xensource.com" List-Id: xen-devel@lists.xenproject.org This is a multi-part message in MIME format. --------------060301020202010505000402 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi George, George Dunlap wrote: > I'm working on revising the scheduler right now, so it's probably best > if you hold off patches for a little while. OK. I'll wait to finish your work. > I'm also trying to understand the minimum that your client workloads > actually need to run well. There were compontents of the "boost" > patch series that helped your workload: > (a) minimum cpu time, > (b) Shortened time slices (2ms) > (c) "boosted" priority for multimedia domains > > Is it possible that having (a) and (b), possibly with some other > combinations, could work well without adding (c)? Yes, it is possible. I divided the rev2 "boost" patch as follows without (c). (1) minimum cpu time (a): boost_1.patch + boost_1_tools.patch (2) Shortened time slices (b): boost_2.patch (3) alternative "boost" mechanism by boost_credit: boost_3.patch These patches works with the following combinations. (1), (1)+(2), (1)+(2)+(3) Please apply these patches in numerical order. Without (3), didn't solve the problem in the paper you showed. Are these what you want? > At any rate, I'm going to start with a revised system that has a > minimum cpu time, but no "high priority", and see if we can get things > to work OK without it. > > Thanks for your work, BTW -- the scheduler has needed some attention > for a long time, but I don't think it would have gotten it if you > hadn't introduced these patches. Thanks. Best regards, Naoki --------------060301020202010505000402 Content-Type: text/x-patch; name="boost_1.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="boost_1.patch" diff -r 56032cbaf1e8 xen/common/sched_credit.c --- a/xen/common/sched_credit.c Thu Jan 22 10:43:50 2009 +0900 +++ b/xen/common/sched_credit.c Thu Jan 22 13:06:24 2009 +0900 @@ -201,6 +201,7 @@ struct csched_vcpu { struct csched_dom *sdom; struct vcpu *vcpu; atomic_t credit; + int prev_credit; uint16_t flags; int16_t pri; #ifdef CSCHED_STATS @@ -225,6 +226,7 @@ struct csched_dom { uint16_t active_vcpu_count; uint16_t weight; uint16_t cap; + uint16_t percent; }; /* @@ -239,6 +241,8 @@ struct csched_private { cpumask_t idlers; uint32_t weight; uint32_t credit; + uint32_t percent; + uint16_t total_percent; int credit_balance; uint32_t runq_sort; CSCHED_STATS_DEFINE() @@ -503,6 +507,7 @@ __csched_vcpu_acct_start_locked(struct c { list_add(&sdom->active_sdom_elem, &csched_priv.active_sdom); csched_priv.weight += sdom->weight; + csched_priv.percent += sdom->percent; } } } @@ -525,6 +530,7 @@ __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.percent -= sdom->percent; } } @@ -579,6 +585,7 @@ csched_vcpu_init(struct vcpu *vc) svc->sdom = sdom; svc->vcpu = vc; atomic_set(&svc->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); @@ -712,25 +719,56 @@ csched_dom_cntl( { op->u.credit.weight = sdom->weight; op->u.credit.cap = sdom->cap; + op->u.credit.percent = sdom->percent; } 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->percent == 0 || op->u.credit.percent == 0) ) + { + weight = op->u.credit.weight; + } + + if ( op->u.credit.cap != (uint16_t)~0U ) + sdom->cap = op->u.credit.cap; + + if ( (op->u.credit.percent != (uint16_t)~0U) && + ((csched_priv.total_percent - sdom->percent + + op->u.credit.percent) <= 100 * csched_priv.ncpus) ) + { + csched_priv.total_percent -= sdom->percent; + csched_priv.total_percent += op->u.credit.percent; + + if ( !list_empty(&sdom->active_sdom_elem) ) + { + csched_priv.percent -= sdom->percent; + csched_priv.percent += op->u.credit.percent; + } + sdom->percent = op->u.credit.percent; + if ( sdom->percent == 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 +797,7 @@ csched_dom_init(struct domain *dom) sdom->dom = dom; sdom->weight = CSCHED_DEFAULT_WEIGHT; sdom->cap = 0U; + sdom->percent = 0U; dom->sched_priv = sdom; return 0; @@ -831,6 +870,7 @@ csched_acct(void) struct csched_dom *sdom; uint32_t credit_total; uint32_t weight_total; + uint32_t percent_credit; uint32_t weight_left; uint32_t credit_fair; uint32_t credit_peak; @@ -857,6 +897,7 @@ csched_acct(void) weight_total = csched_priv.weight; credit_total = csched_priv.credit; + percent_credit = csched_priv.percent * CSCHED_CREDITS_PER_TSLICE / 100; /* Converge balance towards 0 when it drops negative */ if ( csched_priv.credit_balance < 0 ) @@ -865,7 +906,7 @@ csched_acct(void) CSCHED_STAT_CRANK(acct_balance); } - if ( unlikely(weight_total == 0) ) + if ( unlikely(weight_total == 0 && percent_credit == 0) ) { csched_priv.credit_balance = 0; spin_unlock_irqrestore(&csched_priv.lock, flags); @@ -880,22 +921,44 @@ csched_acct(void) credit_xtra = 0; credit_cap = 0U; + /* Firstly, subtract percent_credit from credit_total. */ + if ( percent_credit != 0 ) + { + credit_total -= percent_credit; + credit_balance += percent_credit; + } + + /* 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 == 0 && sdom->percent == 0 ); BUG_ON( sdom->weight > weight_left ); - /* Compute the average of active VCPUs. */ + /* + * Compute the average of active VCPUs + * and adjust credit for comsumption too much. + */ credit_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); + adjust = svc->prev_credit - credit - CSCHED_CREDITS_PER_TSLICE; + if ( adjust > 0 ) + { + atomic_add(adjust, &svc->credit); + } credit_sum += atomic_read(&svc->credit); } credit_average = ( credit_sum + (sdom->active_vcpu_count - 1) @@ -934,7 +997,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 { @@ -963,9 +1028,9 @@ csched_acct(void) } /* Compute fair share per VCPU */ + credit_fair += (sdom->percent * CSCHED_CREDITS_PER_ACCT)/100; credit_fair = ( credit_fair + ( sdom->active_vcpu_count - 1 ) ) / sdom->active_vcpu_count; - list_for_each_safe( iter_vcpu, next_vcpu, &sdom->active_vcpu ) { @@ -1029,6 +1094,9 @@ csched_acct(void) } } + /* save credit for adjustment */ + svc->prev_credit = credit; + CSCHED_VCPU_STAT_SET(svc, credit_last, credit); CSCHED_VCPU_STAT_SET(svc, credit_incr, credit_fair); credit_balance += credit; @@ -1282,7 +1350,10 @@ csched_dump_vcpu(struct csched_vcpu *svc if ( sdom ) { - printk(" credit=%i [w=%u]", atomic_read(&svc->credit), sdom->weight); + printk(" credit=%i [w=%u,p=%u]", + atomic_read(&svc->credit), + sdom->weight, + sdom->percent); #ifdef CSCHED_STATS printk(" (%d+%u) {a/i=%u/%u m=%u+%u}", svc->stats.credit_last, @@ -1348,6 +1419,8 @@ csched_dump(void) "\tcredit balance = %d\n" "\tweight = %u\n" "\trunq_sort = %u\n" + "\tpercent = %u\n" + "\ttotal_percent = %u\n" "\tdefault-weight = %d\n" "\tmsecs per tick = %dms\n" "\tcredits per tick = %d\n" @@ -1359,6 +1432,8 @@ csched_dump(void) csched_priv.credit_balance, csched_priv.weight, csched_priv.runq_sort, + csched_priv.percent, + csched_priv.total_percent, CSCHED_DEFAULT_WEIGHT, CSCHED_MSECS_PER_TICK, CSCHED_CREDITS_PER_TICK, @@ -1412,6 +1487,8 @@ csched_init(void) csched_priv.credit = 0U; csched_priv.credit_balance = 0; csched_priv.runq_sort = 0U; + csched_priv.percent = 0; + csched_priv.total_percent = 0; CSCHED_STATS_RESET(); } diff -r 56032cbaf1e8 xen/include/public/domctl.h --- a/xen/include/public/domctl.h Thu Jan 22 10:43:50 2009 +0900 +++ b/xen/include/public/domctl.h Thu Jan 22 13:06:24 2009 +0900 @@ -311,6 +311,7 @@ struct xen_domctl_scheduler_op { struct xen_domctl_sched_credit { uint16_t weight; uint16_t cap; + uint16_t percent; } credit; } u; }; --------------060301020202010505000402 Content-Type: text/x-patch; name="boost_1_tools.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="boost_1_tools.patch" diff -r 56032cbaf1e8 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Thu Jan 22 10:43:50 2009 +0900 +++ b/tools/python/xen/lowlevel/xc/xc.c Thu Jan 22 12:31:18 2009 +0900 @@ -1285,18 +1285,21 @@ 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 percent; + static char *kwd_list[] = { "domid", "weight", "cap", "percent", NULL }; + static char kwd_type[] = "I|HHh"; struct xen_domctl_sched_credit sdom; weight = 0; cap = (uint16_t)~0U; + percent = (uint16_t)~0U; if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list, - &domid, &weight, &cap) ) + &domid, &weight, &cap, &percent) ) return NULL; sdom.weight = weight; sdom.cap = cap; + sdom.percent = percent; if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 ) return pyxc_error_to_exception(); @@ -1316,9 +1319,10 @@ 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}", + return Py_BuildValue("{s:H,s:H,s:i}", "weight", sdom.weight, - "cap", sdom.cap); + "cap", sdom.cap, + "percent", sdom.percent); } static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args) @@ -1744,6 +1748,8 @@ static PyMethodDef pyxc_methods[] = { "SMP credit scheduler.\n" " domid [int]: domain id to set\n" " weight [short]: domain's scheduling weight\n" + " cap [short]: cap\n" + " percent [short]; domain's scheduling percentage per a cpu\n" "Returns: [int] 0 on success; -1 on error.\n" }, { "sched_credit_domain_get", @@ -1753,7 +1759,9 @@ static PyMethodDef pyxc_methods[] = { "SMP credit scheduler.\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" + " percent [short]: domain's scheduling percentage per a cpu\n"}, { "evtchn_alloc_unbound", (PyCFunction)pyxc_evtchn_alloc_unbound, diff -r 56032cbaf1e8 tools/python/xen/xend/XendAPI.py --- a/tools/python/xen/xend/XendAPI.py Thu Jan 22 10:43:50 2009 +0900 +++ b/tools/python/xen/xend/XendAPI.py Thu Jan 22 12:31:18 2009 +0900 @@ -1505,10 +1505,12 @@ 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 'percent' 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) + percent = xeninfo.info['vcpus_params']['percent'] + xendom.domain_sched_credit_set(xeninfo.getDomid(), weight, cap, percent) def VM_set_VCPUs_number_live(self, _, vm_ref, num): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) diff -r 56032cbaf1e8 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Thu Jan 22 10:43:50 2009 +0900 +++ b/tools/python/xen/xend/XendConfig.py Thu Jan 22 12:31:18 2009 +0900 @@ -591,6 +591,8 @@ 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"]["percent"] = \ + int(sxp.child_value(sxp_cfg, "cpu_percent", 0)) # Only extract options we know about. extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG + \ diff -r 56032cbaf1e8 tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Thu Jan 22 10:43:50 2009 +0900 +++ b/tools/python/xen/xend/XendDomain.py Thu Jan 22 12:31:18 2009 +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 'percent' @return: credit scheduler parameters """ dominfo = self.domain_lookup_nr(domid) @@ -1550,19 +1550,22 @@ class XendDomain: raise XendError(str(ex)) else: return {'weight' : dominfo.getWeight(), - 'cap' : dominfo.getCap()} + 'cap' : dominfo.getCap(), + 'percent': dominfo.getPercent()} - def domain_sched_credit_set(self, domid, weight = None, cap = None): + def domain_sched_credit_set(self, domid, weight = None, cap = None, percent = 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 percent: int @rtype: 0 """ set_weight = False set_cap = False + set_percent = False dominfo = self.domain_lookup_nr(domid) if not dominfo: raise XendInvalidDomain(str(domid)) @@ -1581,17 +1584,27 @@ class XendDomain: else: set_cap = True + if percent is None: + percent = int(~0) + elif percent < 0: + raise XendError("percent is out of range") + else: + set_percent = True + assert type(weight) == int assert type(cap) == int + assert type(percent) == 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, percent) if rc == 0: if set_weight: dominfo.setWeight(weight) if set_cap: dominfo.setCap(cap) + if set_percent: + dominfo.setPercent(percent) self.managed_config_save(dominfo) return rc except Exception, ex: diff -r 56032cbaf1e8 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Thu Jan 22 10:43:50 2009 +0900 +++ b/tools/python/xen/xend/XendDomainInfo.py Thu Jan 22 12:31:18 2009 +0900 @@ -467,7 +467,8 @@ class XendDomainInfo: if xennode.xenschedinfo() == 'credit': xendomains.domain_sched_credit_set(self.getDomid(), self.getWeight(), - self.getCap()) + self.getCap(), + self.getPercent()) except: log.exception('VM start failed') self.destroy() @@ -1705,6 +1706,12 @@ class XendDomainInfo: def setWeight(self, cpu_weight): self.info['vcpus_params']['weight'] = cpu_weight + def getPercent(self): + return self.info['vcpus_params']['percent'] + + def setPercent(self, cpu_percent): + self.info['vcpus_params']['percent'] = cpu_percent + def getRestartCount(self): return self._readVm('xend/restart_count') diff -r 56032cbaf1e8 tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Thu Jan 22 10:43:50 2009 +0900 +++ b/tools/python/xen/xm/main.py Thu Jan 22 12:31:18 2009 +0900 @@ -150,7 +150,7 @@ SUBCOMMAND_HELP = { 'log' : ('', 'Print Xend log'), 'rename' : (' ', 'Rename a domain.'), 'sched-sedf' : (' [options]', 'Get/set EDF parameters.'), - 'sched-credit': ('[-d [-w[=WEIGHT]|-c[=CAP]]]', + 'sched-credit': ('[-d [-w[=WEIGHT]|-c[=CAP]|-p[=PERCENT]]]', 'Get/set credit scheduler parameters.'), 'sysrq' : (' ', 'Send a sysrq to a domain.'), 'debug-keys' : ('', 'Send debug keys to Xen.'), @@ -240,6 +240,7 @@ SUBCOMMAND_OPTIONS = { ('-d DOMAIN', '--domain=DOMAIN', 'Domain to modify'), ('-w WEIGHT', '--weight=WEIGHT', 'Weight (int)'), ('-c CAP', '--cap=CAP', 'Cap (int)'), + ('-p PERCENT', '--percent=PERCENT', 'Percent per a cpu (int)'), ), 'list': ( ('-l', '--long', 'Output all VM details in SXP'), @@ -1578,8 +1579,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:p:", + ["domain=", "weight=", "cap=", "percent="]) except getopt.GetoptError, opterr: err(opterr) usage('sched-credit') @@ -1587,6 +1588,7 @@ def xm_sched_credit(args): domid = None weight = None cap = None + percent = None for o, a in opts: if o in ["-d", "--domain"]: @@ -1594,18 +1596,20 @@ 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 ["-p", "--percent"]: + percent = 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 percent 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 %7s' % ('Name','ID','Weight','Cap','Percent') for d in doms: try: @@ -1618,16 +1622,17 @@ 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 'percent' not in info: # domain does not support sched-credit? - info = {'weight': -1, 'cap': -1} + info = {'weight': -1, 'cap': -1, 'percent':-1} info['weight'] = int(info['weight']) info['cap'] = int(info['cap']) + info['percent'] = int(info['percent']) 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 %(percent)6d") % info) else: if domid is None: # place holder for system-wide scheduler parameters @@ -1644,6 +1649,10 @@ def xm_sched_credit(args): get_single_vm(domid), "cap", cap) + server.xenapi.VM.add_to_VCPUs_params_live( + get_single_vm(domid), + "percent", + percent) else: server.xenapi.VM.add_to_VCPUs_params( get_single_vm(domid), @@ -1653,8 +1662,12 @@ def xm_sched_credit(args): get_single_vm(domid), "cap", cap) + server.xenapi.VM.add_to_VCPUs_params( + get_single_vm(domid), + "percent", + percent) else: - result = server.xend.domain.sched_credit_set(domid, weight, cap) + result = server.xend.domain.sched_credit_set(domid, weight, cap, percent) if result != 0: err(str(result)) --------------060301020202010505000402 Content-Type: text/x-patch; name="boost_2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="boost_2.patch" diff -r 116e2691c071 xen/common/sched_credit.c --- a/xen/common/sched_credit.c Thu Jan 22 13:16:49 2009 +0900 +++ b/xen/common/sched_credit.c Thu Jan 22 13:21:28 2009 +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 /* @@ -245,6 +246,7 @@ struct csched_private { uint16_t total_percent; int credit_balance; uint32_t runq_sort; + s_time_t boost_tslice; CSCHED_STATS_DEFINE() }; @@ -253,6 +255,10 @@ struct csched_private { * Global variables */ 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); @@ -1327,7 +1333,17 @@ 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->start_time = now; @@ -1489,6 +1505,7 @@ csched_init(void) csched_priv.runq_sort = 0U; csched_priv.percent = 0; csched_priv.total_percent = 0; + csched_priv.boost_tslice = MILLISECS(opt_credit_tslice); CSCHED_STATS_RESET(); } --------------060301020202010505000402 Content-Type: text/x-patch; name="boost_3.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="boost_3.patch" diff -r 64618a20b9de xen/common/sched_credit.c --- a/xen/common/sched_credit.c Thu Jan 22 13:22:54 2009 +0900 +++ b/xen/common/sched_credit.c Thu Jan 22 13:42:04 2009 +0900 @@ -202,6 +202,7 @@ 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; @@ -549,14 +550,6 @@ csched_vcpu_acct(unsigned int 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 * migrating it to run elsewhere (see multi-core and multi-thread * support in csched_cpu_pick()). @@ -591,6 +584,7 @@ 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; @@ -706,6 +700,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 */ @@ -954,11 +950,14 @@ csched_acct(void) credit_sum = 0; list_for_each_safe( iter_vcpu, next_vcpu, &sdom->active_vcpu ) { - int adjust; + int adjust, boost_credit; svc = list_entry(iter_vcpu, struct csched_vcpu, active_vcpu_elem); BUG_ON( sdom != svc->sdom ); + boost_credit = atomic_read(&svc->boost_credit); + atomic_set(&svc->boost_credit, 0); + atomic_add(boost_credit, &svc->credit); credit = atomic_read(&svc->credit); adjust = svc->prev_credit - credit - CSCHED_CREDITS_PER_TSLICE; if ( adjust > 0 ) @@ -1290,6 +1289,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); @@ -1366,8 +1381,9 @@ csched_dump_vcpu(struct csched_vcpu *svc if ( sdom ) { - printk(" credit=%i [w=%u,p=%u]", + printk(" credit=%i bc=%i [w=%u,p=%u]", atomic_read(&svc->credit), + atomic_read(&svc->boost_credit), sdom->weight, sdom->percent); #ifdef CSCHED_STATS --------------060301020202010505000402 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --------------060301020202010505000402--