From f744b72e27e086b4e222488b2722f5fcee44888f Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Sat, 31 Jul 2021 23:18:38 +0200 Subject: [PATCH] [v0.98][PPC] Retrieve num caches from udev instead of guessing --- src/common/udev.c | 75 ++++++++++++++++++++++++++++++++++++++++++++--- src/common/udev.h | 10 ++++--- src/ppc/ppc.c | 16 +++++----- 3 files changed, 85 insertions(+), 16 deletions(-) diff --git a/src/common/udev.c b/src/common/udev.c index 596b7da..a1c4c64 100644 --- a/src/common/udev.c +++ b/src/common/udev.c @@ -102,24 +102,91 @@ long get_min_freq_from_file(uint32_t core, bool hv_present) { long get_l1i_cache_size(uint32_t core) { char path[_PATH_CACHE_MAX_LEN]; - sprintf(path, "%s%s/cpu%d%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, core, _PATH_CACHE_L1I); + sprintf(path, "%s%s/cpu%d%s%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, core, _PATH_CACHE_L1I, _PATH_CACHE_SIZE); return get_cache_size_from_file(path); } long get_l1d_cache_size(uint32_t core) { char path[_PATH_CACHE_MAX_LEN]; - sprintf(path, "%s%s/cpu%d%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, core, _PATH_CACHE_L1D); + sprintf(path, "%s%s/cpu%d%s%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, core, _PATH_CACHE_L1D, _PATH_CACHE_SIZE); return get_cache_size_from_file(path); } long get_l2_cache_size(uint32_t core) { char path[_PATH_CACHE_MAX_LEN]; - sprintf(path, "%s%s/cpu%d%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, core, _PATH_CACHE_L2); + sprintf(path, "%s%s/cpu%d%s%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, core, _PATH_CACHE_L2, _PATH_CACHE_SIZE); return get_cache_size_from_file(path); } long get_l3_cache_size(uint32_t core) { char path[_PATH_CACHE_MAX_LEN]; - sprintf(path, "%s%s/cpu%d%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, core, _PATH_CACHE_L3); + sprintf(path, "%s%s/cpu%d%s%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, core, _PATH_CACHE_L3, _PATH_CACHE_SIZE); return get_cache_size_from_file(path); } + +int get_num_caches_from_files(char** paths, int num_paths) { + int SHARED_MAP_MAX_LEN = 8 + 1; + int filelen; + char* buf; + uint32_t* shared_maps = malloc(sizeof(uint32_t *) * num_paths); + + // 1. Read cpu_shared_map from every core + for(int i=0; i < num_paths; i++) { + if((buf = read_file(paths[i], &filelen)) == NULL) { + printWarn("Could not open '%s'", paths[i]); + return -1; + } + + if(filelen > SHARED_MAP_MAX_LEN) { + printBug("Shared map length is %d while the max is be %d", filelen, SHARED_MAP_MAX_LEN); + return -1; + } + + char* end; + errno = 0; + long ret = strtol(buf, &end, 16); + if(errno != 0) { + perror("strtol"); + printBug("Failed parsing '%s' file. Read data was: '%s'", paths[i], buf); + free(buf); + return -1; + } + + shared_maps[i] = (uint32_t) ret; + } + + // 2. Count number of different masks; this is the number of caches + int num_caches = 0; + bool found = false; + uint32_t* unique_shared_maps = malloc(sizeof(uint32_t *) * num_paths); + for(int i=0; i < num_paths; i++) unique_shared_maps[i] = 0; + + for(int i=0; i < num_paths; i++) { + for(int j=0; j < num_paths && !found; j++) { + if(shared_maps[i] == unique_shared_maps[j]) found = true; + } + if(!found) { + unique_shared_maps[num_caches] = shared_maps[i]; + num_caches++; + } + found = false; + } + + return num_caches; +} + +int get_num_caches_by_level(struct cpuInfo* cpu, uint32_t level) { + char** paths = malloc(sizeof(char *) * cpu->topo->total_cores); + for(int i=0; i < cpu->topo->total_cores; i++) { + paths[i] = malloc(sizeof(char) * _PATH_CACHE_MAX_LEN); + sprintf(paths[i], "%s%s/cpu%d%s%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, i, _PATH_CACHE_L3, _PATH_CACHE_SHARED_MAP); + } + + int ret = get_num_caches_from_files(paths, cpu->topo->total_cores); + + for(int i=0; i < cpu->topo->total_cores; i++) + free(paths[i]); + free(paths); + + return ret; +} diff --git a/src/common/udev.h b/src/common/udev.h index 5d35e5f..2c44a9a 100644 --- a/src/common/udev.h +++ b/src/common/udev.h @@ -17,10 +17,12 @@ #define _PATH_FREQUENCY "/cpufreq" #define _PATH_FREQUENCY_MAX "/cpuinfo_max_freq" #define _PATH_FREQUENCY_MIN "/cpuinfo_min_freq" -#define _PATH_CACHE_L1D "/cache/index0/size" -#define _PATH_CACHE_L1I "/cache/index1/size" -#define _PATH_CACHE_L2 "/cache/index2/size" -#define _PATH_CACHE_L3 "/cache/index3/size" +#define _PATH_CACHE_L1D "/cache/index0" +#define _PATH_CACHE_L1I "/cache/index1" +#define _PATH_CACHE_L2 "/cache/index2" +#define _PATH_CACHE_L3 "/cache/index3" +#define _PATH_CACHE_SIZE "/size" +#define _PATH_CACHE_SHARED_MAP "/shared_cpu_map" #define _PATH_FREQUENCY_MAX_LEN 100 #define _PATH_CACHE_MAX_LEN 200 diff --git a/src/ppc/ppc.c b/src/ppc/ppc.c index 3b3a908..2380bf1 100644 --- a/src/ppc/ppc.c +++ b/src/ppc/ppc.c @@ -51,23 +51,23 @@ struct cache* get_cache_info(struct cpuInfo* cpu) { if(cach->L1i->size > 0) { cach->L1i->exists = true; - cach->L1i->num_caches = cpu->topo->physical_cores * cpu->topo->sockets; - cach->max_cache_level++; + cach->L1i->num_caches = get_num_caches_by_level(cpu, 0); + cach->max_cache_level = 1; } if(cach->L1d->size > 0) { cach->L1d->exists = true; - cach->L1d->num_caches = cpu->topo->physical_cores * cpu->topo->sockets; - cach->max_cache_level++; + cach->L1d->num_caches = get_num_caches_by_level(cpu, 1); + cach->max_cache_level = 2; } if(cach->L2->size > 0) { cach->L2->exists = true; - cach->L2->num_caches = cpu->topo->physical_cores * cpu->topo->sockets; - cach->max_cache_level++; + cach->L2->num_caches = get_num_caches_by_level(cpu, 2); + cach->max_cache_level = 3; } if(cach->L3->size > 0) { cach->L3->exists = true; - cach->L3->num_caches = cpu->topo->physical_cores * cpu->topo->sockets; // does not have to be true! - cach->max_cache_level++; + cach->L3->num_caches = get_num_caches_by_level(cpu, 3); + cach->max_cache_level = 4; } return cach;