render / rpms / libvirt

Forked from rpms/libvirt 10 months ago
Clone
7a3408
From 1a4abb61662ff2090ffb1c1f44cc626101742764 Mon Sep 17 00:00:00 2001
7a3408
Message-Id: <1a4abb61662ff2090ffb1c1f44cc626101742764@dist-git>
7a3408
From: Andrea Bolognani <abologna@redhat.com>
7a3408
Date: Wed, 5 Aug 2015 18:18:28 +0200
7a3408
Subject: [PATCH] nodeinfo: Phase out cpu_set_t usage
7a3408
7a3408
Swap out all instances of cpu_set_t and replace them with virBitmap,
7a3408
which some of the code was already using anyway.
7a3408
7a3408
The changes are pretty mechanical, with one notable exception: an
7a3408
assumption has been added on the max value we can run into while
7a3408
reading either socket_it or core_id.
7a3408
7a3408
While this specific assumption was not in place before, we were
7a3408
using cpu_set_t improperly by not making sure not to set any bit
7a3408
past CPU_SETSIZE or explicitly allocating bigger bitmaps; in fact
7a3408
the default size of a cpu_set_t, 1024, is way too low to run our
7a3408
testsuite, which includes core_id values in the 2000s.
7a3408
7a3408
(cherry picked from commit b7b506475ca176276bfaa5dbcdba5b16744b6d56)
7a3408
7a3408
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1213713
7a3408
7a3408
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
7a3408
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
7a3408
---
7a3408
 src/nodeinfo.c | 65 ++++++++++++++++++++++++++++++++++------------------------
7a3408
 1 file changed, 38 insertions(+), 27 deletions(-)
7a3408
7a3408
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
7a3408
index 3550e24..7d0e6b0 100644
7a3408
--- a/src/nodeinfo.c
7a3408
+++ b/src/nodeinfo.c
7a3408
@@ -30,7 +30,6 @@
7a3408
 #include <errno.h>
7a3408
 #include <dirent.h>
7a3408
 #include <sys/utsname.h>
7a3408
-#include <sched.h>
7a3408
 #include "conf/domain_conf.h"
7a3408
 
7a3408
 #if defined(__FreeBSD__) || defined(__APPLE__)
7a3408
@@ -388,19 +387,6 @@ virNodeParseSocket(const char *dir,
7a3408
     return ret;
7a3408
 }
7a3408
 
7a3408
-# ifndef CPU_COUNT
7a3408
-static int
7a3408
-CPU_COUNT(cpu_set_t *set)
7a3408
-{
7a3408
-    size_t i, count = 0;
7a3408
-
7a3408
-    for (i = 0; i < CPU_SETSIZE; i++)
7a3408
-        if (CPU_ISSET(i, set))
7a3408
-            count++;
7a3408
-    return count;
7a3408
-}
7a3408
-# endif /* !CPU_COUNT */
7a3408
-
7a3408
 /* parses a node entry, returning number of processors in the node and
7a3408
  * filling arguments */
7a3408
 static int
7a3408
@@ -415,15 +401,18 @@ virNodeParseNode(const char *sysfs_prefix,
7a3408
                  int *threads,
7a3408
                  int *offline)
7a3408
 {
7a3408
+    /* Biggest value we can expect to be used as either socket id
7a3408
+     * or core id. Bitmaps will need to be sized accordingly */
7a3408
+    const int ID_MAX = 4095;
7a3408
     int ret = -1;
7a3408
     int processors = 0;
7a3408
     DIR *cpudir = NULL;
7a3408
     struct dirent *cpudirent = NULL;
7a3408
     virBitmapPtr present_cpumap = NULL;
7a3408
+    virBitmapPtr sockets_map = NULL;
7a3408
+    virBitmapPtr *cores_maps = NULL;
7a3408
     int sock_max = 0;
7a3408
-    cpu_set_t sock_map;
7a3408
     int sock;
7a3408
-    cpu_set_t *core_maps = NULL;
7a3408
     int core;
7a3408
     size_t i;
7a3408
     int siblings;
7a3408
@@ -445,7 +434,9 @@ virNodeParseNode(const char *sysfs_prefix,
7a3408
         goto cleanup;
7a3408
 
7a3408
     /* enumerate sockets in the node */
7a3408
-    CPU_ZERO(&sock_map);
7a3408
+    if (!(sockets_map = virBitmapNew(ID_MAX + 1)))
7a3408
+        goto cleanup;
7a3408
+
7a3408
     while ((direrr = virDirRead(cpudir, &cpudirent, node)) > 0) {
7a3408
         if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1)
7a3408
             continue;
7a3408
@@ -462,7 +453,15 @@ virNodeParseNode(const char *sysfs_prefix,
7a3408
         /* Parse socket */
7a3408
         if ((sock = virNodeParseSocket(node, arch, cpu)) < 0)
7a3408
             goto cleanup;
7a3408
-        CPU_SET(sock, &sock_map);
7a3408
+        if (sock > ID_MAX) {
7a3408
+            virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                           _("Socket %d can't be handled (max socket is %d)"),
7a3408
+                           sock, ID_MAX);
7a3408
+            goto cleanup;
7a3408
+        }
7a3408
+
7a3408
+        if (virBitmapSetBit(sockets_map, sock) < 0)
7a3408
+            goto cleanup;
7a3408
 
7a3408
         if (sock > sock_max)
7a3408
             sock_max = sock;
7a3408
@@ -473,12 +472,13 @@ virNodeParseNode(const char *sysfs_prefix,
7a3408
 
7a3408
     sock_max++;
7a3408
 
7a3408
-    /* allocate cpu maps for each socket */
7a3408
-    if (VIR_ALLOC_N(core_maps, sock_max) < 0)
7a3408
+    /* allocate cores maps for each socket */
7a3408
+    if (VIR_ALLOC_N(cores_maps, sock_max) < 0)
7a3408
         goto cleanup;
7a3408
 
7a3408
     for (i = 0; i < sock_max; i++)
7a3408
-        CPU_ZERO(&core_maps[i]);
7a3408
+        if (!(cores_maps[i] = virBitmapNew(ID_MAX + 1)))
7a3408
+            goto cleanup;
7a3408
 
7a3408
     /* iterate over all CPU's in the node */
7a3408
     rewinddir(cpudir);
7a3408
@@ -502,7 +502,7 @@ virNodeParseNode(const char *sysfs_prefix,
7a3408
         /* Parse socket */
7a3408
         if ((sock = virNodeParseSocket(node, arch, cpu)) < 0)
7a3408
             goto cleanup;
7a3408
-        if (!CPU_ISSET(sock, &sock_map)) {
7a3408
+        if (!virBitmapIsBitSet(sockets_map, sock)) {
7a3408
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
7a3408
                            _("CPU socket topology has changed"));
7a3408
             goto cleanup;
7a3408
@@ -515,8 +515,15 @@ virNodeParseNode(const char *sysfs_prefix,
7a3408
         } else {
7a3408
             core = virNodeGetCpuValue(node, cpu, "topology/core_id", 0);
7a3408
         }
7a3408
+        if (core > ID_MAX) {
7a3408
+            virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                           _("Core %d can't be handled (max core is %d)"),
7a3408
+                           core, ID_MAX);
7a3408
+            goto cleanup;
7a3408
+        }
7a3408
 
7a3408
-        CPU_SET(core, &core_maps[sock]);
7a3408
+        if (virBitmapSetBit(cores_maps[sock], core) < 0)
7a3408
+            goto cleanup;
7a3408
 
7a3408
         if (!(siblings = virNodeCountThreadSiblings(node, cpu)))
7a3408
             goto cleanup;
7a3408
@@ -529,13 +536,13 @@ virNodeParseNode(const char *sysfs_prefix,
7a3408
         goto cleanup;
7a3408
 
7a3408
     /* finalize the returned data */
7a3408
-    *sockets = CPU_COUNT(&sock_map);
7a3408
+    *sockets = virBitmapCountBits(sockets_map);
7a3408
 
7a3408
     for (i = 0; i < sock_max; i++) {
7a3408
-        if (!CPU_ISSET(i, &sock_map))
7a3408
+        if (!virBitmapIsBitSet(sockets_map, i))
7a3408
             continue;
7a3408
 
7a3408
-        core = CPU_COUNT(&core_maps[i]);
7a3408
+        core = virBitmapCountBits(cores_maps[i]);
7a3408
         if (core > *cores)
7a3408
             *cores = core;
7a3408
     }
7a3408
@@ -548,7 +555,11 @@ virNodeParseNode(const char *sysfs_prefix,
7a3408
         virReportSystemError(errno, _("problem closing %s"), node);
7a3408
         ret = -1;
7a3408
     }
7a3408
-    VIR_FREE(core_maps);
7a3408
+    if (cores_maps)
7a3408
+        for (i = 0; i < sock_max; i++)
7a3408
+            virBitmapFree(cores_maps[i]);
7a3408
+    VIR_FREE(cores_maps);
7a3408
+    virBitmapFree(sockets_map);
7a3408
     virBitmapFree(present_cpumap);
7a3408
 
7a3408
     return ret;
7a3408
-- 
7a3408
2.5.0
7a3408