From df3a51943e4e22d108c36bfda0d081b53513eab0 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 4 Jan 2026 15:07:13 +0300 Subject: [PATCH] [PATCH] util: fix max socket calculation This patch changes how the maximum socket count is calculated. On some systems (e.g. GB200), physical_package_id values are not contiguous or zero-based. Instead of 0..N, they may contain large arbitrary identifiers (e.g. 256123234). The previous implementation assumed a 0..N range and used the maximum ID value directly. This caused: excessive memory allocation extremely large loop bounds OOM / DoS scenarios unnecessary CPU time consumption The new implementation computes the socket count as the number of unique package IDs present on the node, rather than relying on the maximum numeric value. --- src/util/virhostcpu.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c index c3b4f87de1..34c074e6c4 100644 --- a/src/util/virhostcpu.c +++ b/src/util/virhostcpu.c @@ -331,6 +331,8 @@ virHostCPUParseNode(const char *node, int siblings; unsigned int cpu; int direrr; + GHashTable *st = g_hash_table_new(g_direct_hash, g_direct_equal); + gpointer sock_resolved; *threads = 0; *cores = 0; @@ -356,15 +358,29 @@ virHostCPUParseNode(const char *node, if (virHostCPUGetSocket(cpu, &sock) < 0) goto cleanup; - virBitmapSetBitExpand(sockets_map, sock); + if (!g_hash_table_lookup_extended(st, + GUINT_TO_POINTER(sock), + NULL, + &sock_resolved)) { + g_hash_table_insert(st, + GUINT_TO_POINTER(sock), + GUINT_TO_POINTER(sock_max)); + sock = sock_max; + sock_max++; + } else { + sock = GPOINTER_TO_UINT(sock_resolved); + } - if (sock > sock_max) - sock_max = sock; + virBitmapSetBitExpand(sockets_map, sock); } if (direrr < 0) goto cleanup; + if (sock_max == 0) { + g_hash_table_insert(st, GUINT_TO_POINTER(0), GUINT_TO_POINTER(sock_max)); + } + sock_max++; /* allocate cores maps for each socket */ @@ -400,6 +416,16 @@ virHostCPUParseNode(const char *node, if (virHostCPUGetSocket(cpu, &sock) < 0) goto cleanup; + + if (!g_hash_table_lookup_extended(st, + GUINT_TO_POINTER(sock), + NULL, + &sock_resolved)) { + goto cleanup; + } + + sock = GPOINTER_TO_UINT(sock_resolved); + if (!virBitmapIsBitSet(sockets_map, sock)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("CPU socket topology has changed")); @@ -449,6 +475,7 @@ virHostCPUParseNode(const char *node, for (i = 0; i < sock_max; i++) virBitmapFree(cores_maps[i]); VIR_FREE(cores_maps); + g_hash_table_destroy(st); return ret; }