Mesa (main): util: Set util_cpu_caps.num_cpu_mask_bits based on total CPUs in the system

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 15 20:26:14 UTC 2021


Module: Mesa
Branch: main
Commit: c12b52b8567ebb06ef141a7432ea1abdf868bb3d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c12b52b8567ebb06ef141a7432ea1abdf868bb3d

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Tue Jun  8 16:36:32 2021 -0700

util: Set util_cpu_caps.num_cpu_mask_bits based on total CPUs in the system

In the current code, this prevents a very unlikely corner case.  More
importantly, it should prevent the next commit from breaking the
universe.

Imagine a system with 64 CPUs configured, but first 32 CPUs are offline.
_SC_NPROCESSORS_CONF will return 32.  All of the surrounding code will
interpret this as meaning CPUs 0 through 31, but all of those CPUs are
offline.  Nothing good can happen then.

The problem cases require systems with more than 32 CPUs because
util_cpu_caps.num_cpu_mask_bits is always rounded up to a multiple of
32.

Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11228>

---

 src/util/u_cpu_detect.c | 42 +++++++++++++++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 9 deletions(-)

diff --git a/src/util/u_cpu_detect.c b/src/util/u_cpu_detect.c
index 03a1d79fd58..6925b096c23 100644
--- a/src/util/u_cpu_detect.c
+++ b/src/util/u_cpu_detect.c
@@ -555,6 +555,9 @@ get_cpu_topology(void)
 static void
 util_cpu_detect_once(void)
 {
+   int available_cpus = 0;
+   int total_cpus = 0;
+
    memset(&util_cpu_caps, 0, sizeof util_cpu_caps);
 
    /* Count the number of CPUs in system */
@@ -562,7 +565,7 @@ util_cpu_detect_once(void)
    {
       SYSTEM_INFO system_info;
       GetSystemInfo(&system_info);
-      util_cpu_caps.nr_cpus = MAX2(1, system_info.dwNumberOfProcessors);
+      available_cpus = MAX2(1, system_info.dwNumberOfProcessors);
    }
 #elif defined(PIPE_OS_UNIX)
    /* Linux, FreeBSD, DragonFly, and Mac OS X should have
@@ -576,12 +579,33 @@ util_cpu_detect_once(void)
       int len = sizeof(ncpu);
 
       sysctl(mib, 2, &ncpu, &len, NULL, 0);
-      util_cpu_caps.nr_cpus = ncpu;
+      available_cpus = ncpu;
    }
 #  elif defined(_SC_NPROCESSORS_ONLN)
-   util_cpu_caps.nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
-   if (util_cpu_caps.nr_cpus == ~0)
-      util_cpu_caps.nr_cpus = 1;
+   available_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+   if (available_cpus == ~0)
+      available_cpus = 1;
+#  elif defined(PIPE_OS_BSD)
+   {
+      const int mib[] = { CTL_HW, HW_NCPU };
+      int ncpu;
+      int len = sizeof(ncpu);
+
+      sysctl(mib, 2, &ncpu, &len, NULL, 0);
+      available_cpus = ncpu;
+   }
+#  endif /* defined(PIPE_OS_BSD) */
+
+   /* Determine the maximum number of CPUs configured in the system.  This is
+    * used to properly set num_cpu_mask_bits below.  On BSDs that don't have
+    * HW_NCPUONLINE, it was not clear whether HW_NCPU is the number of
+    * configured or the number of online CPUs.  For that reason, prefer the
+    * _SC_NPROCESSORS_CONF path on all BSDs.
+    */
+#  if defined(_SC_NPROCESSORS_CONF)
+   total_cpus = sysconf(_SC_NPROCESSORS_CONF);
+   if (total_cpus == ~0)
+      total_cpus = 1;
 #  elif defined(PIPE_OS_BSD)
    {
       const int mib[] = { CTL_HW, HW_NCPU };
@@ -589,15 +613,15 @@ util_cpu_detect_once(void)
       int len = sizeof(ncpu);
 
       sysctl(mib, 2, &ncpu, &len, NULL, 0);
-      util_cpu_caps.nr_cpus = ncpu;
+      total_cpus = ncpu;
    }
 #  endif /* defined(PIPE_OS_BSD) */
 #endif /* defined(PIPE_OS_UNIX) */
 
-   if (util_cpu_caps.nr_cpus == 0)
-      util_cpu_caps.nr_cpus = 1;
+   util_cpu_caps.nr_cpus = MAX2(1, available_cpus);
+   total_cpus = MAX2(total_cpus, util_cpu_caps.nr_cpus);
 
-   util_cpu_caps.num_cpu_mask_bits = align(util_cpu_caps.nr_cpus, 32);
+   util_cpu_caps.num_cpu_mask_bits = align(total_cpus, 32);
 
    /* Make the fallback cacheline size nonzero so that it can be
     * safely passed to align().



More information about the mesa-commit mailing list