[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.