aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-01-06 10:13:55 +0000
committerKeir Fraser <keir.fraser@citrix.com>2010-01-06 10:13:55 +0000
commita78d15f98666de4e98a37e84eeda748c86e48e11 (patch)
treed324619dddcc25d2fad15e9d34ee8a4367769524
parent5da045d64736cec6b8678110715b73abc7290af6 (diff)
downloadxen-a78d15f98666de4e98a37e84eeda748c86e48e11.tar.gz
xen-a78d15f98666de4e98a37e84eeda748c86e48e11.tar.bz2
xen-a78d15f98666de4e98a37e84eeda748c86e48e11.zip
sysctl: Return max_node_id rather than nr_nodes from physinfo command.
Python extension continues to synthesise a nr_nodes value. Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
-rw-r--r--tools/python/xen/lowlevel/xc/xc.c73
-rw-r--r--xen/arch/ia64/xen/dom0_ops.c2
-rw-r--r--xen/arch/x86/sysctl.c2
-rw-r--r--xen/include/public/sysctl.h4
-rw-r--r--xen/include/xen/nodemask.h24
5 files changed, 58 insertions, 47 deletions
diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c
index 8a9537e9c4..e7f06d6a9e 100644
--- a/tools/python/xen/lowlevel/xc/xc.c
+++ b/tools/python/xen/lowlevel/xc/xc.c
@@ -1078,7 +1078,7 @@ static PyObject *pyxc_physinfo(XcObject *self)
#define MAX_CPU_ID 255
xc_physinfo_t info;
char cpu_cap[128], virt_caps[128], *p;
- int i, j, max_cpu_id;
+ int i, j, max_cpu_id, nr_nodes = 0;
uint64_t free_heap;
PyObject *ret_obj, *node_to_cpu_obj, *node_to_memory_obj;
PyObject *node_to_dma32_mem_obj;
@@ -1105,64 +1105,63 @@ static PyObject *pyxc_physinfo(XcObject *self)
if ( p != virt_caps )
*(p-1) = '\0';
- ret_obj = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s: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,
- "nr_cpus", info.nr_cpus,
- "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,
- "virt_caps", virt_caps);
-
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. */
+ /* Construct node-to-* lists. */
node_to_cpu_obj = PyList_New(0);
-
- /* Make a list for each node. */
- for ( i = 0; i < info.nr_nodes; i++ )
+ node_to_memory_obj = PyList_New(0);
+ node_to_dma32_mem_obj = PyList_New(0);
+ for ( i = 0; i <= info.max_node_id; i++ )
{
+ int node_exists = 0;
+ PyObject *pyint;
+
+ /* CPUs. */
PyObject *cpus = PyList_New(0);
for ( j = 0; j <= max_cpu_id; j++ )
- if ( i == map[j]) {
- PyObject *pyint = PyInt_FromLong(j);
- PyList_Append(cpus, pyint);
- Py_DECREF(pyint);
- }
+ {
+ if ( i != map[j] )
+ continue;
+ pyint = PyInt_FromLong(j);
+ PyList_Append(cpus, pyint);
+ Py_DECREF(pyint);
+ node_exists = 1;
+ }
PyList_Append(node_to_cpu_obj, cpus);
Py_DECREF(cpus);
- }
-
- node_to_memory_obj = PyList_New(0);
-
- for ( i = 0; i < info.nr_nodes; i++ )
- {
- PyObject *pyint;
+ /* Memory. */
xc_availheap(self->xc_handle, 0, 0, i, &free_heap);
+ node_exists = node_exists || (free_heap != 0);
pyint = PyInt_FromLong(free_heap / 1024);
PyList_Append(node_to_memory_obj, pyint);
Py_DECREF(pyint);
- }
- /* DMA memory. */
- node_to_dma32_mem_obj = PyList_New(0);
-
- for ( i = 0; i < info.nr_nodes; i++ )
- {
- PyObject *pyint;
+ /* DMA memory. */
xc_availheap(self->xc_handle, 0, 32, i, &free_heap);
pyint = PyInt_FromLong(free_heap / 1024);
PyList_Append(node_to_dma32_mem_obj, pyint);
Py_DECREF(pyint);
+
+ if ( node_exists )
+ nr_nodes++;
}
+ ret_obj = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s:s:s}",
+ "nr_nodes", nr_nodes,
+ "max_node_id", info.max_node_id,
+ "max_cpu_id", info.max_cpu_id,
+ "threads_per_core", info.threads_per_core,
+ "cores_per_socket", info.cores_per_socket,
+ "nr_cpus", info.nr_cpus,
+ "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,
+ "virt_caps", virt_caps);
PyDict_SetItemString(ret_obj, "node_to_cpu", node_to_cpu_obj);
Py_DECREF(node_to_cpu_obj);
PyDict_SetItemString(ret_obj, "node_to_memory", node_to_memory_obj);
diff --git a/xen/arch/ia64/xen/dom0_ops.c b/xen/arch/ia64/xen/dom0_ops.c
index d5a971e84b..5c521c96cb 100644
--- a/xen/arch/ia64/xen/dom0_ops.c
+++ b/xen/arch/ia64/xen/dom0_ops.c
@@ -715,12 +715,12 @@ long arch_do_sysctl(xen_sysctl_t *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
pi->cores_per_socket =
cpus_weight(per_cpu(cpu_core_map, 0)) / pi->threads_per_core;
pi->nr_cpus = (u32)num_online_cpus();
- pi->nr_nodes = num_online_nodes();
pi->total_pages = total_pages;
pi->free_pages = avail_domheap_pages();
pi->scrub_pages = 0;
pi->cpu_khz = local_cpu_data->proc_freq / 1000;
+ pi->max_node_id = last_node(node_online_map);
pi->max_cpu_id = last_cpu(cpu_online_map);
max_array_ent = min_t(uint32_t, max_array_ent, pi->max_cpu_id);
diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c
index 27bda34e6e..c08cb3d4bd 100644
--- a/xen/arch/x86/sysctl.c
+++ b/xen/arch/x86/sysctl.c
@@ -64,7 +64,6 @@ long arch_do_sysctl(
pi->cores_per_socket =
cpus_weight(per_cpu(cpu_core_map, 0)) / pi->threads_per_core;
pi->nr_cpus = (u32)num_online_cpus();
- pi->nr_nodes = num_online_nodes();
pi->total_pages = total_pages;
pi->free_pages = avail_domheap_pages();
pi->scrub_pages = 0;
@@ -75,6 +74,7 @@ long arch_do_sysctl(
if ( iommu_enabled )
pi->capabilities |= XEN_SYSCTL_PHYSCAP_hvm_directio;
+ pi->max_node_id = last_node(node_online_map);
pi->max_cpu_id = last_cpu(cpu_online_map);
max_array_ent = min_t(uint32_t, max_array_ent, pi->max_cpu_id);
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 926eaf183e..f869f9c5af 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -34,7 +34,7 @@
#include "xen.h"
#include "domctl.h"
-#define XEN_SYSCTL_INTERFACE_VERSION 0x00000006
+#define XEN_SYSCTL_INTERFACE_VERSION 0x00000007
/*
* Read console content from Xen buffer ring.
@@ -94,7 +94,7 @@ struct xen_sysctl_physinfo {
uint32_t threads_per_core;
uint32_t cores_per_socket;
uint32_t nr_cpus;
- uint32_t nr_nodes;
+ uint32_t max_node_id;
uint32_t cpu_khz;
uint64_aligned_t total_pages;
uint64_aligned_t free_pages;
diff --git a/xen/include/xen/nodemask.h b/xen/include/xen/nodemask.h
index 30ed6f4524..84ebfa95ad 100644
--- a/xen/include/xen/nodemask.h
+++ b/xen/include/xen/nodemask.h
@@ -38,6 +38,7 @@
*
* int first_node(mask) Number lowest set bit, or MAX_NUMNODES
* int next_node(node, mask) Next node past 'node', or MAX_NUMNODES
+ * int last_node(mask) Number highest set bit, or MAX_NUMNODES
* int first_unset_node(mask) First node not set in mask, or
* MAX_NUMNODES.
*
@@ -214,16 +215,27 @@ static inline void __nodes_shift_left(nodemask_t *dstp,
/* FIXME: better would be to fix all architectures to never return
> MAX_NUMNODES, then the silly min_ts could be dropped. */
-#define first_node(src) __first_node(&(src))
-static inline int __first_node(const nodemask_t *srcp)
+#define first_node(src) __first_node(&(src), MAX_NUMNODES)
+static inline int __first_node(const nodemask_t *srcp, int nbits)
{
- return min_t(int, MAX_NUMNODES, find_first_bit(srcp->bits, MAX_NUMNODES));
+ return min_t(int, nbits, find_first_bit(srcp->bits, nbits));
}
-#define next_node(n, src) __next_node((n), &(src))
-static inline int __next_node(int n, const nodemask_t *srcp)
+#define next_node(n, src) __next_node((n), &(src), MAX_NUMNODES)
+static inline int __next_node(int n, const nodemask_t *srcp, int nbits)
{
- return min_t(int,MAX_NUMNODES,find_next_bit(srcp->bits, MAX_NUMNODES, n+1));
+ return min_t(int, nbits, find_next_bit(srcp->bits, nbits, n+1));
+}
+
+#define last_node(src) __last_node(&(src), MAX_NUMNODES)
+static inline int __last_node(const nodemask_t *srcp, int nbits)
+{
+ int node, pnode = nbits;
+ for (node = __first_node(srcp, nbits);
+ node < nbits;
+ node = __next_node(node, srcp, nbits))
+ pnode = node;
+ return pnode;
}
#define nodemask_of_node(node) \