[PATCH] util: Fix max socket calculation

Alexandr Semenikhin posted 1 patch 3 weeks, 5 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/20260106103139.101923-1-alexandr2e78@gmail.com
src/util/virhostcpu.c | 32 +++++++++++++++++++++++++++++---
1 file changed, 29 insertions(+), 3 deletions(-)
[PATCH] util: Fix max socket calculation
Posted by Alexandr Semenikhin 3 weeks, 5 days ago
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.

Signed-off-by: Alexandr Semenikhin <alexandr2e78@gmail.com>
---
 src/util/virhostcpu.c | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index 09395ddb04..113aa6881e 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;
+    g_autoptr(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"));
-- 
2.47.3
Re: [PATCH] util: Fix max socket calculation
Posted by Daniel P. Berrangé via Devel 2 weeks, 2 days ago
On Tue, Jan 06, 2026 at 10:31:29AM +0000, Alexandr Semenikhin wrote:
> 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.
> 
> Signed-off-by: Alexandr Semenikhin <alexandr2e78@gmail.com>
> ---
>  src/util/virhostcpu.c | 32 +++++++++++++++++++++++++++++---
>  1 file changed, 29 insertions(+), 3 deletions(-)

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>

and pushed.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|