Cpu bitmap is split into 32 bit words. For system with more than 32 cores threads are always in different words thus first word never has two bits: cpu0: "0000,00000100,00000001", cpu 79: "8000,00000080,00000000".
Instead of parsing bitmap read "core_cpus_list" or "thread_siblings_list" and simply check presence of ',' or '-' in it. Signed-off-by: Konstantin Khlebnikov <khlebni...@yandex-team.ru> Fixes: de5077c4e38f ("perf tools: Add utility function to detect SMT status") --- tools/perf/util/smt.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/tools/perf/util/smt.c b/tools/perf/util/smt.c index 8481842e9edb..dc37b5abd1c3 100644 --- a/tools/perf/util/smt.c +++ b/tools/perf/util/smt.c @@ -1,6 +1,7 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <string.h> #include <linux/bitops.h> #include "api/fs/fs.h" #include "smt.h" @@ -9,39 +10,35 @@ int smt_on(void) { static bool cached; static int cached_result; + int active; int cpu; int ncpu; + char *str = NULL; + size_t strlen; if (cached) return cached_result; ncpu = sysconf(_SC_NPROCESSORS_CONF); for (cpu = 0; cpu < ncpu; cpu++) { - unsigned long long siblings; - char *str; - size_t strlen; char fn[256]; - snprintf(fn, sizeof fn, - "devices/system/cpu/cpu%d/topology/core_cpus", cpu); - if (sysfs__read_str(fn, &str, &strlen) < 0) { - snprintf(fn, sizeof fn, - "devices/system/cpu/cpu%d/topology/thread_siblings", - cpu); - if (sysfs__read_str(fn, &str, &strlen) < 0) - continue; - } - /* Entry is hex, but does not have 0x, so need custom parser */ - siblings = strtoull(str, NULL, 16); - free(str); - if (hweight64(siblings) > 1) { - cached_result = 1; - cached = true; + snprintf(fn, sizeof(fn), "devices/system/cpu/cpu%d/topology/%s", + cpu, "core_cpus_list"); + if (sysfs__read_str(fn, &str, &strlen) > 0) + break; + + snprintf(fn, sizeof(fn), "devices/system/cpu/cpu%d/topology/%s", + cpu, "thread_siblings_list"); + if (sysfs__read_str(fn, &str, &strlen) > 0) break; - } } + + active = str && (strchr(str, ',') != NULL || strchr(str, '-') != NULL); + free(str); + if (!cached) { - cached_result = 0; + cached_result = active; cached = true; } return cached_result;