debuggers.hg

changeset 21233:3e56823eb209

xend: fix best NUMA node allocation

Since we moved several NUMA info fields from physinfo into separate
functions/structures, we must adapt the node picking algorithm, too.
Currently xm create complains about undefined hash values.
The patch uses the new Python xc binding to get the information and
create a reverse mapping for node_to_cpu, since we now only have a
cpu_to_node field.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Apr 15 17:36:16 2010 +0100 (2010-04-15)
parents 2c2591185f8c
children ffffddc4b1e0
files tools/python/xen/xend/XendDomainInfo.py
line diff
     1.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Apr 15 13:16:17 2010 +0100
     1.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Apr 15 17:36:16 2010 +0100
     1.3 @@ -2711,7 +2711,7 @@ class XendDomainInfo:
     1.4          else:
     1.5              def find_relaxed_node(node_list):
     1.6                  import sys
     1.7 -                nr_nodes = info['max_node_id']+1
     1.8 +                nr_nodes = info['max_node_index'] + 1
     1.9                  if node_list is None:
    1.10                      node_list = range(0, nr_nodes)
    1.11                  nodeload = [0]
    1.12 @@ -2724,35 +2724,40 @@ class XendDomainInfo:
    1.13                          if sxp.child_value(vcpu, 'online') == 0: continue
    1.14                          cpumap = list(sxp.child_value(vcpu,'cpumap'))
    1.15                          for i in range(0, nr_nodes):
    1.16 -                            node_cpumask = info['node_to_cpu'][i]
    1.17 +                            node_cpumask = node_to_cpu[i]
    1.18                              for j in node_cpumask:
    1.19                                  if j in cpumap:
    1.20                                      nodeload[i] += 1
    1.21                                      break
    1.22                  for i in range(0, nr_nodes):
    1.23 -                    if len(info['node_to_cpu'][i]) == 0:
    1.24 +                    if len(node_to_cpu[i]) == 0:
    1.25                          nodeload[i] += 8
    1.26                      else:
    1.27 -                        nodeload[i] = int(nodeload[i] * 16 / len(info['node_to_cpu'][i]))
    1.28 +                        nodeload[i] = int(nodeload[i] * 16 / len(node_to_cpu[i]))
    1.29                          if i not in node_list:
    1.30                              nodeload[i] += 8
    1.31                  return map(lambda x: x[0], sorted(enumerate(nodeload), key=lambda x:x[1]))
    1.32  
    1.33 -            info = xc.physinfo()
    1.34 -            if info['nr_nodes'] > 1:
    1.35 -                node_memory_list = info['node_to_memory']
    1.36 +            info = xc.numainfo()
    1.37 +            if info['max_node_index'] > 0:
    1.38 +                node_memory_list = info['node_memfree']
    1.39 +                node_to_cpu = []
    1.40 +                for i in range(0, info['max_node_index'] + 1):
    1.41 +                    node_to_cpu.append([])
    1.42 +                for cpu, node in enumerate(xc.topologyinfo()['cpu_to_node']):
    1.43 +                    node_to_cpu[node].append(cpu)
    1.44                  needmem = self.image.getRequiredAvailableMemory(self.info['memory_dynamic_max']) / 1024
    1.45                  candidate_node_list = []
    1.46 -                for i in range(0, info['max_node_id']+1):
    1.47 -                    if node_memory_list[i] >= needmem and len(info['node_to_cpu'][i]) > 0:
    1.48 +                for i in range(0, info['max_node_index'] + 1):
    1.49 +                    if node_memory_list[i] >= needmem and len(node_to_cpu[i]) > 0:
    1.50                          candidate_node_list.append(i)
    1.51                  best_node = find_relaxed_node(candidate_node_list)[0]
    1.52 -                cpumask = info['node_to_cpu'][best_node]
    1.53 -                best_nodes = find_relaxed_node(filter(lambda x: x != best_node, range(0,info['max_node_id']+1)))
    1.54 +                cpumask = node_to_cpu[best_node]
    1.55 +                best_nodes = find_relaxed_node(filter(lambda x: x != best_node, range(0,info['max_node_index']+1)))
    1.56                  for node_idx in best_nodes:
    1.57                      if len(cpumask) >= self.info['VCPUs_max']:
    1.58                          break
    1.59 -                    cpumask = cpumask + info['node_to_cpu'][node_idx]
    1.60 +                    cpumask = cpumask + node_to_cpu[node_idx]
    1.61                      log.debug("allocating additional NUMA node %d", node_idx)
    1.62                  for v in range(0, self.info['VCPUs_max']):
    1.63                      xc.vcpu_setaffinity(self.domid, v, cpumask)