powerpc-utils/powerpc-utils-1.3.13-cpu_info_helpers.patch

164 lines
5.5 KiB
Diff

commit 54cf30c7d274c8aab2a7ae589ab056f52dfffc62
Author: Aboorva Devarajan <aboorvad@linux.ibm.com>
Date: Sat Dec 7 21:54:44 2024 -0500
cpu_info_helpers: Add helper function to retrieve present CPU core list
Introduce get_present_core_list helper function to accurately parse
and retrieve the list of present CPU cores, addressing gaps in core
numbering caused by dynamic addition or removal of CPUs (via CPU DLPAR
operation)
Utilizes the present CPU list from `sys/devices/system/cpu/present`
to handle non-contiguous CPU IDs. Accurately maps core IDs to CPUs
considering specified number of threads per CPU, addressing gaps in
core numbering.
Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
diff --git a/src/common/cpu_info_helpers.c b/src/common/cpu_info_helpers.c
index 8c57db8..756e792 100644
--- a/src/common/cpu_info_helpers.c
+++ b/src/common/cpu_info_helpers.c
@@ -203,6 +203,113 @@ int __get_one_smt_state(int core, int threads_per_cpu)
return smt_state;
}
+int get_present_cpu_count(void)
+{
+ int start, end, total_cpus = 0;
+ size_t len = 0;
+ char *line = NULL;
+ FILE *fp;
+ char *token;
+
+ fp = fopen(CPU_PRESENT_PATH, "r");
+ if (!fp) {
+ perror("Error opening CPU_PRESENT_PATH");
+ return -1;
+ }
+
+ if (getline(&line, &len, fp) == -1) {
+ perror("Error reading CPU_PRESENT_PATH");
+ fclose(fp);
+ free(line);
+ return -1;
+ }
+ fclose(fp);
+
+ token = strtok(line, ",");
+ while (token) {
+ if (sscanf(token, "%d-%d", &start, &end) == 2) {
+ total_cpus += (end - start + 1);
+ } else if (sscanf(token, "%d", &start) == 1) {
+ total_cpus++;
+ }
+ token = strtok(NULL, ",");
+ }
+
+ free(line);
+ return total_cpus;
+}
+
+int get_present_core_list(int **present_cores, int *num_present_cores, int threads_per_cpu)
+{
+ FILE *fp = NULL;
+ char *line = NULL;
+ char *token = NULL;
+ size_t len = 0;
+ ssize_t read;
+ int core_count = 0;
+ int core_list_size;
+ int *cores = NULL;
+ int start, end, i;
+
+ if (threads_per_cpu <= 0) {
+ fprintf(stderr, "Invalid threads_per_cpu value, got %d expected >= 1\n", threads_per_cpu);
+ return -1;
+ }
+
+ core_list_size = get_present_cpu_count() / threads_per_cpu;
+ if (core_list_size <= 0) {
+ fprintf(stderr, "Error while calculating core list size\n");
+ return -1;
+ }
+
+ cores = malloc(core_list_size * sizeof(int));
+ if (!cores) {
+ perror("Memory allocation failed");
+ goto cleanup;
+ }
+
+ fp = fopen(CPU_PRESENT_PATH, "r");
+ if (!fp) {
+ perror("Error opening file");
+ goto cleanup;
+ }
+
+ read = getline(&line, &len, fp);
+ if (read == -1) {
+ perror("Error reading file");
+ goto cleanup;
+ }
+
+ token = strtok(line, ",");
+ while (token) {
+ if (sscanf(token, "%d-%d", &start, &end) == 2) {
+ for (i = start; i <= end; i++) {
+ if (i % threads_per_cpu == 0) {
+ cores[core_count++] = i / threads_per_cpu;
+ }
+ }
+ } else if (sscanf(token, "%d", &start) == 1) {
+ if (start % threads_per_cpu == 0) {
+ cores[core_count++] = start / threads_per_cpu;
+ }
+ }
+ token = strtok(NULL, ",");
+ }
+
+ *present_cores = cores;
+ *num_present_cores = core_count;
+ free(line);
+ return 0;
+
+cleanup:
+ if (fp) {
+ fclose(fp);
+ }
+ free(line);
+ free(cores);
+ return -1;
+}
+
static void print_cpu_list(const cpu_set_t *cpuset, int cpuset_size,
int cpus_in_system)
{
diff --git a/src/common/cpu_info_helpers.h b/src/common/cpu_info_helpers.h
index c063fff..77e6ad7 100644
--- a/src/common/cpu_info_helpers.h
+++ b/src/common/cpu_info_helpers.h
@@ -24,9 +24,10 @@
#ifndef _CPU_INFO_HELPERS_H
#define _CPU_INFO_HELPERS_H
-#define SYSFS_CPUDIR "/sys/devices/system/cpu/cpu%d"
-#define SYSFS_SUBCORES "/sys/devices/system/cpu/subcores_per_core"
-#define INTSERV_PATH "/proc/device-tree/cpus/%s/ibm,ppc-interrupt-server#s"
+#define SYSFS_CPUDIR "/sys/devices/system/cpu/cpu%d"
+#define SYSFS_SUBCORES "/sys/devices/system/cpu/subcores_per_core"
+#define INTSERV_PATH "/proc/device-tree/cpus/%s/ibm,ppc-interrupt-server#s"
+#define CPU_PRESENT_PATH "/sys/devices/system/cpu/present"
#define SYSFS_PATH_MAX 128
@@ -39,6 +40,8 @@ extern int num_subcores(void);
extern int get_attribute(char *path, const char *fmt, int *value);
extern int get_cpu_info(int *threads_per_cpu, int *cpus_in_system,
int *threads_in_system);
+extern int get_present_core_list(int **present_cores, int *num_present_cores,
+ int threads_per_cpu);
extern int __is_smt_capable(int threads_in_system);
extern int __get_one_smt_state(int core, int threads_per_cpu);
extern int __do_smt(bool numeric, int cpus_in_system, int threads_per_cpu,