This patch adds data gathering to the NUMA gathering files and adds
support for outputting the data. The test driver and xend driver need to
be adapted to fill sensible data to the structure.
---
src/conf/capabilities.c | 14 +++++++++++--
src/nodeinfo.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++---
src/test/test_driver.c | 3 +++
src/xen/xend_internal.c | 3 +++
4 files changed, 70 insertions(+), 5 deletions(-)
diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
index 814c4d6..49eb0a7 100644
--- a/src/conf/capabilities.c
+++ b/src/conf/capabilities.c
@@ -698,9 +698,19 @@ virCapabilitiesFormatNUMATopology(virBufferPtr xml,
for (i = 0; i < ncells; i++) {
virBufferAsprintf(xml, " <cell id='%d'>\n",
cells[i]->num);
virBufferAsprintf(xml, " <cpus num='%d'>\n",
cells[i]->ncpus);
- for (j = 0; j < cells[i]->ncpus; j++)
- virBufferAsprintf(xml, " <cpu
id='%d'/>\n",
+ for (j = 0; j < cells[i]->ncpus; j++) {
+ virBufferAsprintf(xml, " <cpu id='%d'",
cells[i]->cpus[j].id);
+ if (cells[i]->cpus[j].core_id >= 0 &&
+ cells[i]->cpus[j].socket_id >= 0 &&
+ cells[i]->cpus[j].siblings_list)
+ virBufferAsprintf(xml, " socket_id='%d' core_id='%d'
siblings='%s'",
+ cells[i]->cpus[j].socket_id,
+ cells[i]->cpus[j].core_id,
+ cells[i]->cpus[j].siblings_list);
+ virBufferAddLit(xml, "/>\n");
+ }
+
virBufferAddLit(xml, " </cpus>\n");
virBufferAddLit(xml, " </cell>\n");
}
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index dffe7d1..ec20609 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -1472,6 +1472,52 @@ cleanup:
# define MASK_CPU_ISSET(mask, cpu) \
(((mask)[((cpu) / n_bits(*(mask)))] >> ((cpu) % n_bits(*(mask)))) & 1)
+static char *
+virNodeGetSiblingsList(const char *dir, int cpu_id)
+{
+ char *path = NULL;
+ char *buf = NULL;
+ char *newline;
+
+ if (virAsprintf(&path, "%s/cpu%u/topology/thread_siblings_list",
+ dir, cpu_id) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ if (virFileReadAll(path, SYSFS_THREAD_SIBLINGS_LIST_LENGHT_MAX, &buf) < 0)
+ goto error;
+
+ if ((newline = strchr(buf, '\n')))
+ *newline = '\0';
+
+ VIR_FREE(path);
+ return buf;
+
+error:
+ VIR_FREE(path);
+ VIR_FREE(buf);
+ return NULL;
+}
+
+static int
+virNodeCapsFillCPUInfo(int cpu_id, virCapsHostNUMACellCPUPtr cpu)
+{
+ cpu->id = cpu_id;
+ cpu->socket_id = virNodeGetCpuValue(SYSFS_CPU_PATH, cpu_id,
+ "topology/physical_package_id", -1);
+ cpu->core_id = virNodeGetCpuValue(SYSFS_CPU_PATH, cpu_id,
+ "topology/core_id", -1);
+
+ if (cpu->socket_id == -1 || cpu->core_id == -1)
+ return 0;
+
+ if (!(cpu->siblings_list = virNodeGetSiblingsList(SYSFS_CPU_PATH, cpu_id)))
+ return -1;
+
+ return 0;
+}
+
int
nodeCapsInitNUMA(virCapsPtr caps)
{
@@ -1515,9 +1561,12 @@ nodeCapsInitNUMA(virCapsPtr caps)
if (VIR_ALLOC_N(cpus, ncpus) < 0)
goto cleanup;
- for (ncpus = 0, i = 0 ; i < max_n_cpus ; i++)
- if (MASK_CPU_ISSET(mask, i))
- cpus[ncpus++].id = i;
+ for (ncpus = 0, i = 0 ; i < max_n_cpus ; i++) {
+ if (MASK_CPU_ISSET(mask, i)) {
+ if (virNodeCapsFillCPUInfo(i, cpus + ncpus++) < 0)
+ goto cleanup;
+ }
+ }
if (virCapabilitiesAddHostNUMACell(caps, n, ncpus, cpus) < 0)
goto cleanup;
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 6909fa4..7693f75 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -559,6 +559,9 @@ static int testOpenDefault(virConnectPtr conn) {
}
for (u = 0 ; u < 16 ; u++) {
privconn->cells[u % 2].cpus[(u / 2)].id = u;
+ privconn->cells[u % 2].cpus[(u / 2)].socket_id = -1;
+ privconn->cells[u % 2].cpus[(u / 2)].core_id = -1;
+ privconn->cells[u % 2].cpus[(u / 2)].siblings_list = NULL;
}
if (!(privconn->caps = testBuildCapabilities(conn)))
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index d39d0b1..bfb02f7 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -1161,6 +1161,9 @@ sexpr_to_xend_topology(const struct sexpr *root,
ignore_value(virBitmapGetBit(cpuset, cpu, &used));
if (used) {
cpuInfo[n].id = cpu;
+ cpuInfo[n].core_id = -1;
+ cpuInfo[n].socket_id = -1;
+ cpuInfo[n].siblings_list = NULL;
n++;
}
}
--
1.8.1.1