mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Extended the physinfo sysctl to export NUMA cpu_to_node topology info.
Print this in 'xm info'. Signed-off-by: Ryan Harper <ryanh@us.ibm.com> Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
8d374ca1d1
commit
be259653f3
13 files changed
+166
-77
No files matched your search
@@ -680,33 +680,62 @@ static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
|
||||
|
||||
static PyObject *pyxc_physinfo(XcObject *self)
|
||||
{
|
||||
#define MAX_CPU_ID 255
|
||||
xc_physinfo_t info;
|
||||
char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
|
||||
int i;
|
||||
|
||||
int i, j, max_cpu_id;
|
||||
PyObject *ret_obj, *node_to_cpu_obj;
|
||||
xc_cpu_to_node_t map[MAX_CPU_ID];
|
||||
|
||||
set_xen_guest_handle(info.cpu_to_node, map);
|
||||
info.max_cpu_id = MAX_CPU_ID;
|
||||
|
||||
if ( xc_physinfo(self->xc_handle, &info) != 0 )
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
*q=0;
|
||||
for(i=0;i<sizeof(info.hw_cap)/4;i++)
|
||||
*q = 0;
|
||||
for ( i = 0; i < sizeof(info.hw_cap)/4; i++ )
|
||||
{
|
||||
p+=sprintf(p,"%08x:",info.hw_cap[i]);
|
||||
if(info.hw_cap[i])
|
||||
q=p;
|
||||
p += sprintf(p, "%08x:", info.hw_cap[i]);
|
||||
if ( info.hw_cap[i] )
|
||||
q = p;
|
||||
}
|
||||
if(q>cpu_cap)
|
||||
*(q-1)=0;
|
||||
if ( q > cpu_cap )
|
||||
*(q-1) = 0;
|
||||
|
||||
return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
|
||||
"threads_per_core", info.threads_per_core,
|
||||
"cores_per_socket", info.cores_per_socket,
|
||||
"sockets_per_node", info.sockets_per_node,
|
||||
"nr_nodes", info.nr_nodes,
|
||||
"total_memory", pages_to_kib(info.total_pages),
|
||||
"free_memory", pages_to_kib(info.free_pages),
|
||||
"scrub_memory", pages_to_kib(info.scrub_pages),
|
||||
"cpu_khz", info.cpu_khz,
|
||||
"hw_caps", cpu_cap);
|
||||
ret_obj = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
|
||||
"nr_nodes", info.nr_nodes,
|
||||
"max_cpu_id", info.max_cpu_id,
|
||||
"threads_per_core", info.threads_per_core,
|
||||
"cores_per_socket", info.cores_per_socket,
|
||||
"sockets_per_node", info.sockets_per_node,
|
||||
"total_memory", pages_to_kib(info.total_pages),
|
||||
"free_memory", pages_to_kib(info.free_pages),
|
||||
"scrub_memory", pages_to_kib(info.scrub_pages),
|
||||
"cpu_khz", info.cpu_khz,
|
||||
"hw_caps", cpu_cap);
|
||||
|
||||
max_cpu_id = info.max_cpu_id;
|
||||
if ( max_cpu_id > MAX_CPU_ID )
|
||||
max_cpu_id = MAX_CPU_ID;
|
||||
|
||||
/* Construct node-to-cpu lists. */
|
||||
node_to_cpu_obj = PyList_New(0);
|
||||
|
||||
/* Make a list for each node. */
|
||||
for ( i = 0; i < info.nr_nodes; i++ )
|
||||
{
|
||||
PyObject *cpus = PyList_New(0);
|
||||
for ( j = 0; j <= max_cpu_id; j++ )
|
||||
if ( i == map[j])
|
||||
PyList_Append(cpus, PyInt_FromLong(j));
|
||||
PyList_Append(node_to_cpu_obj, cpus);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(ret_obj, "node_to_cpu", node_to_cpu_obj);
|
||||
|
||||
return ret_obj;
|
||||
#undef MAX_CPU_ID
|
||||
}
|
||||
|
||||
static PyObject *pyxc_xeninfo(XcObject *self)
|
||||
|
||||
@@ -533,6 +533,54 @@ class XendNode:
|
||||
['version', ver],
|
||||
['machine', mch]]
|
||||
|
||||
def list_to_rangepairs(self,cmap):
|
||||
cmap.sort()
|
||||
pairs = []
|
||||
x = y = 0
|
||||
for i in range(0,len(cmap)):
|
||||
try:
|
||||
if ((cmap[y+1] - cmap[i]) > 1):
|
||||
pairs.append((cmap[x],cmap[y]))
|
||||
x = y = i+1
|
||||
else:
|
||||
y = y + 1
|
||||
# if we go off the end, then just add x to y
|
||||
except IndexError:
|
||||
pairs.append((cmap[x],cmap[y]))
|
||||
|
||||
return pairs
|
||||
|
||||
def format_pairs(self,pairs):
|
||||
if not pairs:
|
||||
return "no cpus"
|
||||
out = ""
|
||||
for f,s in pairs:
|
||||
if (f==s):
|
||||
out += '%d'%f
|
||||
else:
|
||||
out += '%d-%d'%(f,s)
|
||||
out += ','
|
||||
# trim trailing ','
|
||||
return out[:-1]
|
||||
|
||||
def list_to_strrange(self,list):
|
||||
return self.format_pairs(self.list_to_rangepairs(list))
|
||||
|
||||
def format_node_to_cpu(self, pinfo):
|
||||
str=''
|
||||
whitespace=''
|
||||
try:
|
||||
node_to_cpu=pinfo['node_to_cpu']
|
||||
for i in range(0, pinfo['nr_nodes']):
|
||||
str+='%snode%d:%s\n' % (whitespace,
|
||||
i,
|
||||
self.list_to_strrange(node_to_cpu[i]))
|
||||
whitespace='%25s' % ''
|
||||
except:
|
||||
str='none\n'
|
||||
return str[:-1];
|
||||
|
||||
|
||||
def physinfo(self):
|
||||
info = self.xc.physinfo()
|
||||
|
||||
@@ -545,6 +593,7 @@ class XendNode:
|
||||
# physinfo is in KiB, need it in MiB
|
||||
info['total_memory'] = info['total_memory'] / 1024
|
||||
info['free_memory'] = info['free_memory'] / 1024
|
||||
info['node_to_cpu'] = self.format_node_to_cpu(info)
|
||||
|
||||
ITEM_ORDER = ['nr_cpus',
|
||||
'nr_nodes',
|
||||
@@ -555,6 +604,7 @@ class XendNode:
|
||||
'hw_caps',
|
||||
'total_memory',
|
||||
'free_memory',
|
||||
'node_to_cpu'
|
||||
]
|
||||
|
||||
return [[k, info[k]] for k in ITEM_ORDER]
|
||||
|
||||