From 716706d0a7d1b3c11e9153f66a6c0280bb529605 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Sun, 22 Nov 2020 15:18:15 +0100 Subject: [PATCH] [v0.88][ARM][BUGFIX] Fetch number of cores from /sys/devices/system/cpu/present file, instead of /proc/cpuinfo. Pay attention to cases where frequency and/or MIDR can not be fetched from cpuinfo. This happens when the CPU has offline cores --- src/arm/midr.c | 33 ++++++++++++++++++++++++--------- src/common/main.c | 2 +- src/common/udev.c | 40 ++++++++++++++++++++++++++++++---------- src/common/udev.h | 1 + 4 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/arm/midr.c b/src/arm/midr.c index 0ded9d5..ee9924f 100644 --- a/src/arm/midr.c +++ b/src/arm/midr.c @@ -5,6 +5,7 @@ #include #include "../common/udev.h" +#include "../common/global.h" #include "midr.h" #include "uarch.h" @@ -131,6 +132,11 @@ struct cpuInfo* get_cpu_info() { for(int i=0; i < ncores; i++) { midr_array[i] = get_midr_from_cpuinfo(i); + + if(midr_array[i] == UNKNOWN) { + printWarn("Unable to fetch MIDR for core %d. This is probably because the core is offline", i); + midr_array[i] = midr_array[0]; + } } uint32_t sockets = fill_ids_from_midr(midr_array, ids_array, ncores); @@ -213,16 +219,25 @@ char* get_soc_name(struct cpuInfo* cpu) { void print_debug(struct cpuInfo* cpu) { int ncores = get_ncores_from_cpuinfo(); - if(ncores >= 10) { - for(int i=0; i < ncores; i++) { - printf("[Core %02d] 0x%.8X %ld MHz\n", i, get_midr_from_cpuinfo(i), get_max_freq_from_file(i)); + for(int i=0; i < ncores; i++) { + printf("[Core %d] ", i); + long freq = get_max_freq_from_file(i); + uint32_t midr = get_midr_from_cpuinfo(i); + if(midr == UNKNOWN) { + printWarn("Unable to fetch MIDR for core %d. This is probably because the core is offline", i); + printf("0x%.8X ", get_midr_from_cpuinfo(0)); } - } - else { - for(int i=0; i < ncores; i++) { - printf("[Core %d] 0x%.8X %ld MHz\n", i, get_midr_from_cpuinfo(i), get_max_freq_from_file(i)); - } - } + else { + printf("0x%.8X ", midr); + } + if(freq == UNKNOWN_FREQ) { + printWarn("Unable to fetch max frequency for core %d. This is probably because the core is offline", i); + printf("%ld MHz\n", get_max_freq_from_file(0)); + } + else { + printf("%ld MHz\n", freq); + } + } } void free_topo_struct(struct topology* topo) { diff --git a/src/common/main.c b/src/common/main.c index 2ca4862..81de6d8 100644 --- a/src/common/main.c +++ b/src/common/main.c @@ -13,7 +13,7 @@ #include "../arm/midr.h" #endif -static const char* VERSION = "0.87"; +static const char* VERSION = "0.88"; void print_help(char *argv[]) { printf("Usage: %s [--version] [--help] [--debug] [--style \"fancy\"|\"retro\"|\"legacy\"] [--color \"intel\"|\"amd\"|'R,G,B:R,G,B:R,G,B:R,G,B']\n\n", argv[0]); diff --git a/src/common/udev.c b/src/common/udev.c index 0566524..32919d6 100644 --- a/src/common/udev.c +++ b/src/common/udev.c @@ -5,6 +5,7 @@ #include #include +#include "udev.h" #include "global.h" #ifdef ARCH_X86 @@ -25,9 +26,13 @@ long get_freq_from_file(char* path) { int fd = open(path, O_RDONLY); - if(fd == -1) { + if(fd == -1) { + #ifdef ARCH_X86 perror("open"); printBug("Could not open '%s'", path); + #elif ARCH_ARM + printWarn("Could not open '%s'", path); + #endif return UNKNOWN_FREQ; } @@ -83,7 +88,7 @@ long get_min_freq_from_file(uint32_t core) { #ifdef ARCH_ARM -#define UNKNOWN -1 +#define _PATH_CPUS_PRESENT _PATH_SYS_SYSTEM _PATH_SYS_CPU "/present" #define _PATH_CPUINFO "/proc/cpuinfo" #define CPUINFO_CPU_IMPLEMENTER_STR "CPU implementer\t: " @@ -94,10 +99,16 @@ long get_min_freq_from_file(uint32_t core) { #define CPUINFO_CPU_STRING "processor" +// https://www.kernel.org/doc/html/latest/core-api/cpu_hotplug.html int get_ncores_from_cpuinfo() { - int fd = open(_PATH_CPUINFO, O_RDONLY); - + // Examples: + // 0-271 + // 0-5 + // 0-7 + int fd = open(_PATH_CPUS_PRESENT, O_RDONLY); + if(fd == -1) { + fprintf(stderr, "%s: ", _PATH_CPUS_PRESENT); perror("open"); return UNKNOWN; } @@ -114,12 +125,18 @@ int get_ncores_from_cpuinfo() { } int ncores = 0; - char* tmp = buf; - do { - tmp++; - ncores++; - tmp = strstr(tmp, CPUINFO_CPU_STRING); - } while(tmp != NULL); + char* tmp1 = strstr(buf, "-") + 1; + char* tmp2 = strstr(buf, "\n"); + char ncores_str[offset]; + memcpy(ncores_str, tmp1, tmp2-tmp1); + + char* end; + errno = 0; + ncores = strtol(ncores_str, &end, 10) + 1; + if(errno != 0) { + perror("strtol"); + return UNKNOWN; + } free(buf); @@ -173,6 +190,9 @@ uint32_t get_midr_from_cpuinfo(uint32_t core) { current_core++; tmp = strstr(tmp, CPUINFO_CPU_STRING); } + + if(tmp == NULL) + return UNKNOWN; uint32_t cpu_implementer; uint32_t cpu_architecture; diff --git a/src/common/udev.h b/src/common/udev.h index 3161b1f..f6ea540 100644 --- a/src/common/udev.h +++ b/src/common/udev.h @@ -7,6 +7,7 @@ long get_max_freq_from_file(uint32_t core); long get_min_freq_from_file(uint32_t core); #ifdef ARCH_ARM +#define UNKNOWN -1 int get_ncores_from_cpuinfo(); uint32_t get_midr_from_cpuinfo(uint32_t core); #endif