[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] xend: Improve "cpus" parameter to be able to define CPU affinities for each VCPU
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1210241758 -3600 # Node ID 5c3df1bded8249219dfae4f5a9820636f73aa944 # Parent d7dbae33e81d45c86a0a02cc1537144351e38df8 xend: Improve "cpus" parameter to be able to define CPU affinities for each VCPU If we define the form of list of string to "cpus" parameter, different CPU affinities are set for each VCPU as follows. # grep cpus /etc/xen/vm1 cpus = ["2", "3"] vcpus = 2 # xm create vm1 Using config file "/etc/xen/vm1". Started domain vm1 # xm vcpu-list vm1 Name ID VCPU CPU State Time(s) CPU Affinity vm1 1 0 2 r-- 3.5 2 vm1 1 1 3 -b- 3.2 3 If we define the form of string to "cpus" parameter as before, a same CPU affinity is set for each VCPU as follows. # grep cpus /etc/xen/vm2 cpus = "2,3" vcpus = 2 # xm create vm2 Using config file "/etc/xen/vm2". Started domain vm2 # xm vcpu-list vm2 Name ID VCPU CPU State Time(s) CPU Affinity vm2 2 0 3 -b- 3.0 2-3 vm2 2 1 2 r-- 2.6 2-3 Signed-off-by: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx> --- tools/python/xen/xend/XendConfig.py | 108 +++++++++++++++++++++----------- tools/python/xen/xend/XendDomain.py | 31 ++++----- tools/python/xen/xend/XendDomainInfo.py | 23 +++++- 3 files changed, 106 insertions(+), 56 deletions(-) diff -r d7dbae33e81d -r 5c3df1bded82 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Thu May 08 11:13:51 2008 +0100 +++ b/tools/python/xen/xend/XendConfig.py Thu May 08 11:15:58 2008 +0100 @@ -640,46 +640,84 @@ class XendConfig(dict): else: cfg['cpus'] = str(cfg['cpu']) - # Convert 'cpus' to list of ints + # Convert 'cpus' to list of list of ints + cpus_list = [] if 'cpus' in cfg: - cpus = [] + # Convert the following string to list of ints. + # The string supports a list of ranges (0-3), + # seperated by commas, and negation (^1). + # Precedence is settled by order of the string: + # "0-3,^1" -> [0,2,3] + # "0-3,^1,1" -> [0,1,2,3] + def cnv(s): + l = [] + for c in s.split(','): + if c.find('-') != -1: + (x, y) = c.split('-') + for i in range(int(x), int(y)+1): + l.append(int(i)) + else: + # remove this element from the list + if c[0] == '^': + l = [x for x in l if x != int(c[1:])] + else: + l.append(int(c)) + return l + if type(cfg['cpus']) == list: - # If sxp_cfg was created from config.sxp, - # the form of 'cpus' is list of string. - # Convert 'cpus' to list of ints. - # ['1'] -> [1] - # ['0','2','3'] -> [0,2,3] + if len(cfg['cpus']) > 0 and type(cfg['cpus'][0]) == list: + # If sxp_cfg was created from config.sxp, + # the form of 'cpus' is list of list of string. + # Convert 'cpus' to list of list of ints. + # Conversion examples: + # [['1']] -> [[1]] + # [['0','2'],['1','3']] -> [[0,2],[1,3]] + try: + for c1 in cfg['cpus']: + cpus = [] + for c2 in c1: + cpus.append(int(c2)) + cpus_list.append(cpus) + except ValueError, e: + raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e)) + else: + # Conversion examples: + # ["1"] -> [[1]] + # ["0,2","1,3"] -> [[0,2],[1,3]] + # ["0-3,^1","1-4,^2"] -> [[0,2,3],[1,3,4]] + try: + for c in cfg['cpus']: + cpus = cnv(c) + cpus_list.append(cpus) + except ValueError, e: + raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e)) + + if len(cpus_list) != cfg['vcpus']: + raise XendConfigError('vcpus and the item number of cpus are not same') + else: + # Conversion examples: + # vcpus=1: + # "1" -> [[1]] + # "0-3,^1" -> [[0,2,3]] + # vcpus=2: + # "1" -> [[1],[1]] + # "0-3,^1" -> [[0,2,3],[0,2,3]] try: - for c in cfg['cpus']: - cpus.append(int(c)) - - cfg['cpus'] = cpus + cpus = cnv(cfg['cpus']) + for v in range(0, cfg['vcpus']): + cpus_list.append(cpus) except ValueError, e: raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e)) - else: - # Convert 'cpus' string to list of ints - # 'cpus' supports a list of ranges (0-3), - # seperated by commas, and negation, (^1). - # Precedence is settled by order of the - # string: - # "0-3,^1" -> [0,2,3] - # "0-3,^1,1" -> [0,1,2,3] - try: - for c in cfg['cpus'].split(','): - if c.find('-') != -1: - (x, y) = c.split('-') - for i in range(int(x), int(y)+1): - cpus.append(int(i)) - else: - # remove this element from the list - if c[0] == '^': - cpus = [x for x in cpus if x != int(c[1:])] - else: - cpus.append(int(c)) - - cfg['cpus'] = cpus - except ValueError, e: - raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e)) + else: + # Generation examples: + # vcpus=1: + # -> [[]] + # vcpus=2: + # -> [[],[]] + for v in range(0, cfg['vcpus']): + cpus_list.append(list()) + + cfg['cpus'] = cpus_list # Parse cpuid if 'cpuid' in cfg: diff -r d7dbae33e81d -r 5c3df1bded82 tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Thu May 08 11:13:51 2008 +0100 +++ b/tools/python/xen/xend/XendDomain.py Thu May 08 11:15:58 2008 +0100 @@ -1365,28 +1365,25 @@ class XendDomain: raise XendInvalidDomain(str(domid)) # if vcpu is keyword 'all', apply the cpumap to all vcpus - vcpus = [ vcpu ] if str(vcpu).lower() == "all": vcpus = range(0, int(dominfo.getVCpuCount())) + else: + vcpus = [ int(vcpu) ] # set the same cpumask for all vcpus rc = 0 - if dominfo._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED): - for v in vcpus: - try: - rc = xc.vcpu_setaffinity(dominfo.getDomid(), int(v), cpumap) - except Exception, ex: - log.exception(ex) - raise XendError("Cannot pin vcpu: %s to cpu: %s - %s" % \ - (v, cpumap, str(ex))) - else: - # FIXME: if we could define cpu affinity definitions to - # each vcpu, reprogram the following processing. - if str(vcpu).lower() != "all": - raise XendError("Must specify 'all' to VCPU " - "for inactive managed domains") - dominfo.setCpus(cpumap) - self.managed_config_save(dominfo) + cpus = dominfo.getCpus() + for v in vcpus: + try: + if dominfo._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED): + rc = xc.vcpu_setaffinity(dominfo.getDomid(), v, cpumap) + cpus[v] = cpumap + except Exception, ex: + log.exception(ex) + raise XendError("Cannot pin vcpu: %d to cpu: %s - %s" % \ + (v, cpumap, str(ex))) + dominfo.setCpus(cpus) + self.managed_config_save(dominfo) return rc diff -r d7dbae33e81d -r 5c3df1bded82 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Thu May 08 11:13:51 2008 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Thu May 08 11:15:58 2008 +0100 @@ -1051,8 +1051,8 @@ class XendDomainInfo: ['running', 0], ['cpu_time', 0.0], ['cpu', -1], - ['cpumap', self.info['cpus'] and \ - self.info['cpus'] or range(64)]]) + ['cpumap', self.info['cpus'][i] and \ + self.info['cpus'][i] or range(64)]]) return sxpr @@ -1477,6 +1477,13 @@ class XendDomainInfo: self.info['VCPUs_live'] = vcpus self._writeDom(self._vcpuDomDetails()) else: + if self.info['VCPUs_max'] > vcpus: + # decreasing + del self.info['cpus'][vcpus:] + elif self.info['VCPUs_max'] < vcpus: + # increasing + for c in range(self.info['VCPUs_max'], vcpus): + self.info['cpus'].append(list()) self.info['VCPUs_max'] = vcpus xen.xend.XendDomain.instance().managed_config_save(self) log.info("Set VCPU count on domain %s to %d", self.info['name_label'], @@ -2071,9 +2078,17 @@ class XendDomainInfo: # repin domain vcpus if a restricted cpus list is provided # this is done prior to memory allocation to aide in memory # distribution for NUMA systems. - if self.info['cpus'] is not None and len(self.info['cpus']) > 0: + def has_cpus(): + if self.info['cpus'] is not None: + for c in self.info['cpus']: + if c: + return True + return False + + if has_cpus(): for v in range(0, self.info['VCPUs_max']): - xc.vcpu_setaffinity(self.domid, v, self.info['cpus']) + if self.info['cpus'][v]: + xc.vcpu_setaffinity(self.domid, v, self.info['cpus'][v]) else: def find_relaxed_node(node_list): import sys _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |