ia64/xen-unstable

changeset 18783:76e90ac5067e

xend: Restore CPU affinity on domain resume.

Move affinity-setting logic into its own function and call from
relevant places.

From: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Nov 11 11:06:27 2008 +0000 (2008-11-11)
parents beade55d67fc
children 36bda0bb805f
files tools/python/xen/xend/XendDomainInfo.py
line diff
     1.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Tue Nov 11 11:03:58 2008 +0000
     1.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Nov 11 11:06:27 2008 +0000
     1.3 @@ -479,6 +479,7 @@ class XendDomainInfo:
     1.4          if state in (DOM_STATE_SUSPENDED, DOM_STATE_HALTED):
     1.5              try:
     1.6                  self._constructDomain()
     1.7 +                self._setCPUAffinity()
     1.8                  self._storeVmDetails()
     1.9                  self._createChannels()
    1.10                  self._createDevices()
    1.11 @@ -2166,6 +2167,64 @@ class XendDomainInfo:
    1.12              raise XendError(str(exn))
    1.13  
    1.14  
    1.15 +    def _setCPUAffinity(self):
    1.16 +        """ Repin domain vcpus if a restricted cpus list is provided
    1.17 +        """
    1.18 +
    1.19 +        def has_cpus():
    1.20 +            if self.info['cpus'] is not None:
    1.21 +                for c in self.info['cpus']:
    1.22 +                    if c:
    1.23 +                        return True
    1.24 +            return False
    1.25 +
    1.26 +        if has_cpus():
    1.27 +            for v in range(0, self.info['VCPUs_max']):
    1.28 +                if self.info['cpus'][v]:
    1.29 +                    xc.vcpu_setaffinity(self.domid, v, self.info['cpus'][v])
    1.30 +        else:
    1.31 +            def find_relaxed_node(node_list):
    1.32 +                import sys
    1.33 +                nr_nodes = info['nr_nodes']
    1.34 +                if node_list is None:
    1.35 +                    node_list = range(0, nr_nodes)
    1.36 +                nodeload = [0]
    1.37 +                nodeload = nodeload * nr_nodes
    1.38 +                from xen.xend import XendDomain
    1.39 +                doms = XendDomain.instance().list('all')
    1.40 +                for dom in filter (lambda d: d.domid != self.domid, doms):
    1.41 +                    cpuinfo = dom.getVCPUInfo()
    1.42 +                    for vcpu in sxp.children(cpuinfo, 'vcpu'):
    1.43 +                        if sxp.child_value(vcpu, 'online') == 0: continue
    1.44 +                        cpumap = list(sxp.child_value(vcpu,'cpumap'))
    1.45 +                        for i in range(0, nr_nodes):
    1.46 +                            node_cpumask = info['node_to_cpu'][i]
    1.47 +                            for j in node_cpumask:
    1.48 +                                if j in cpumap:
    1.49 +                                    nodeload[i] += 1
    1.50 +                                    break
    1.51 +                for i in range(0, nr_nodes):
    1.52 +                    if len(info['node_to_cpu'][i]) > 0 and i in node_list:
    1.53 +                        nodeload[i] = int(nodeload[i] * 16 / len(info['node_to_cpu'][i]))
    1.54 +                    else:
    1.55 +                        nodeload[i] = sys.maxint
    1.56 +                index = nodeload.index( min(nodeload) )    
    1.57 +                return index
    1.58 +
    1.59 +            info = xc.physinfo()
    1.60 +            if info['nr_nodes'] > 1:
    1.61 +                node_memory_list = info['node_to_memory']
    1.62 +                needmem = self.image.getRequiredAvailableMemory(self.info['memory_dynamic_max']) / 1024
    1.63 +                candidate_node_list = []
    1.64 +                for i in range(0, info['nr_nodes']):
    1.65 +                    if node_memory_list[i] >= needmem and len(info['node_to_cpu'][i]) > 0:
    1.66 +                        candidate_node_list.append(i)
    1.67 +                index = find_relaxed_node(candidate_node_list)
    1.68 +                cpumask = info['node_to_cpu'][index]
    1.69 +                for v in range(0, self.info['VCPUs_max']):
    1.70 +                    xc.vcpu_setaffinity(self.domid, v, cpumask)
    1.71 +
    1.72 +
    1.73      def _initDomain(self):
    1.74          log.debug('XendDomainInfo.initDomain: %s %s',
    1.75                    self.domid,
    1.76 @@ -2185,58 +2244,7 @@ class XendDomainInfo:
    1.77              # repin domain vcpus if a restricted cpus list is provided
    1.78              # this is done prior to memory allocation to aide in memory
    1.79              # distribution for NUMA systems.
    1.80 -            def has_cpus():
    1.81 -                if self.info['cpus'] is not None:
    1.82 -                    for c in self.info['cpus']:
    1.83 -                        if c:
    1.84 -                            return True
    1.85 -                return False
    1.86 -
    1.87 -            if has_cpus():
    1.88 -                for v in range(0, self.info['VCPUs_max']):
    1.89 -                    if self.info['cpus'][v]:
    1.90 -                        xc.vcpu_setaffinity(self.domid, v, self.info['cpus'][v])
    1.91 -            else:
    1.92 -                def find_relaxed_node(node_list):
    1.93 -                    import sys
    1.94 -                    nr_nodes = info['nr_nodes']
    1.95 -                    if node_list is None:
    1.96 -                        node_list = range(0, nr_nodes)
    1.97 -                    nodeload = [0]
    1.98 -                    nodeload = nodeload * nr_nodes
    1.99 -                    from xen.xend import XendDomain
   1.100 -                    doms = XendDomain.instance().list('all')
   1.101 -                    for dom in filter (lambda d: d.domid != self.domid, doms):
   1.102 -                        cpuinfo = dom.getVCPUInfo()
   1.103 -                        for vcpu in sxp.children(cpuinfo, 'vcpu'):
   1.104 -                            if sxp.child_value(vcpu, 'online') == 0: continue
   1.105 -                            cpumap = list(sxp.child_value(vcpu,'cpumap'))
   1.106 -                            for i in range(0, nr_nodes):
   1.107 -                                node_cpumask = info['node_to_cpu'][i]
   1.108 -                                for j in node_cpumask:
   1.109 -                                    if j in cpumap:
   1.110 -                                        nodeload[i] += 1
   1.111 -                                        break
   1.112 -                    for i in range(0, nr_nodes):
   1.113 -                        if len(info['node_to_cpu'][i]) > 0 and i in node_list:
   1.114 -                            nodeload[i] = int(nodeload[i] * 16 / len(info['node_to_cpu'][i]))
   1.115 -                        else:
   1.116 -                            nodeload[i] = sys.maxint
   1.117 -                    index = nodeload.index( min(nodeload) )    
   1.118 -                    return index
   1.119 -
   1.120 -                info = xc.physinfo()
   1.121 -                if info['nr_nodes'] > 1:
   1.122 -                    node_memory_list = info['node_to_memory']
   1.123 -                    needmem = self.image.getRequiredAvailableMemory(self.info['memory_dynamic_max']) / 1024
   1.124 -                    candidate_node_list = []
   1.125 -                    for i in range(0, info['nr_nodes']):
   1.126 -                        if node_memory_list[i] >= needmem and len(info['node_to_cpu'][i]) > 0:
   1.127 -                            candidate_node_list.append(i)
   1.128 -                    index = find_relaxed_node(candidate_node_list)
   1.129 -                    cpumask = info['node_to_cpu'][index]
   1.130 -                    for v in range(0, self.info['VCPUs_max']):
   1.131 -                        xc.vcpu_setaffinity(self.domid, v, cpumask)
   1.132 +            self._setCPUAffinity()
   1.133  
   1.134              # Use architecture- and image-specific calculations to determine
   1.135              # the various headrooms necessary, given the raw configured