164 lines
5.5 KiB
Diff
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,
|