From 0cc93a460319294d085a5642b55050fadf39100e Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 15 Mar 2023 10:26:13 -0400 Subject: [PATCH] util/cpu: add big.LITTLE cpu detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit it's useful for drivers to be able to detect big.LITTLE topology in order to make decisions about how to handle workloads (specifically as it relates to threading) Reviewed-by: Rob Clark Reviewed-by: Marek Olšák Part-of: --- src/util/u_cpu_detect.c | 35 +++++++++++++++++++++++++++++++++++ src/util/u_cpu_detect.h | 11 +++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/util/u_cpu_detect.c b/src/util/u_cpu_detect.c index 5a9baddfb87..2357c4f9780 100644 --- a/src/util/u_cpu_detect.c +++ b/src/util/u_cpu_detect.c @@ -38,6 +38,7 @@ #include "util/u_debug.h" #include "u_cpu_detect.h" #include "u_math.h" +#include "os_file.h" #include "c11/threads.h" #include @@ -478,6 +479,40 @@ get_cpu_topology(void) memset(util_cpu_caps.cpu_to_L3, 0xff, sizeof(util_cpu_caps.cpu_to_L3)); +#if DETECT_OS_LINUX + uint64_t big_cap = 0; + unsigned num_big_cpus = 0; + uint64_t *caps = malloc(sizeof(uint64_t) * util_cpu_caps.max_cpus); + bool fail = false; + for (unsigned i = 0; caps && i < util_cpu_caps.max_cpus; i++) { + char name[PATH_MAX]; + snprintf(name, sizeof(name), "/sys/devices/system/cpu/cpu%u/cpu_capacity", i); + size_t size = 0; + char *cap = os_read_file(name, &size); + if (!cap) { + num_big_cpus = 0; + fail = true; + break; + } + errno = 0; + caps[i] = strtoull(cap, NULL, 10); + free(cap); + if (errno) { + fail = true; + break; + } + big_cap = MAX2(caps[i], big_cap); + } + if (!fail) { + for (unsigned i = 0; caps && i < util_cpu_caps.max_cpus; i++) { + if (caps[i] >= big_cap / 2) + num_big_cpus++; + } + } + free(caps); + util_cpu_caps.nr_big_cpus = num_big_cpus; +#endif + #if DETECT_ARCH_X86 || DETECT_ARCH_X86_64 /* AMD Zen */ if (util_cpu_caps.family >= CPU_AMD_ZEN1_ZEN2 && diff --git a/src/util/u_cpu_detect.h b/src/util/u_cpu_detect.h index 0c59a008a6b..f9db16f82da 100644 --- a/src/util/u_cpu_detect.h +++ b/src/util/u_cpu_detect.h @@ -126,8 +126,19 @@ struct util_cpu_caps_t { unsigned max_vector_bits; uint16_t cpu_to_L3[UTIL_MAX_CPUS]; + /* Affinity masks for each L3 cache. */ util_affinity_mask *L3_affinity_mask; + /** + * number of "big" CPUs in big.LITTLE configuration + * + * a "big" CPU is defined as anything with >= 50% the capacity of the largest CPU, + * useful for drivers determining how many and what kinds of threads to use + * example: 1x prime + 3x big + 4x little = 4x "big" cores + * + * A value of zero indicates that CPUs are homogeneous. + */ + int16_t nr_big_cpus; }; struct _util_cpu_caps_state_t {