Skip to content

Commit d6a771d

Browse files
AboorvaDevarajantyreld
authored andcommitted
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 <[email protected]> Signed-off-by: Tyrel Datwyler <[email protected]>
1 parent 3a8127a commit d6a771d

File tree

2 files changed

+113
-3
lines changed

2 files changed

+113
-3
lines changed

src/common/cpu_info_helpers.c

+107
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,113 @@ int __get_one_smt_state(int core, int threads_per_cpu)
203203
return smt_state;
204204
}
205205

206+
int get_present_cpu_count(void)
207+
{
208+
int start, end, total_cpus = 0;
209+
size_t len = 0;
210+
char *line = NULL;
211+
FILE *fp;
212+
char *token;
213+
214+
fp = fopen(CPU_PRESENT_PATH, "r");
215+
if (!fp) {
216+
perror("Error opening CPU_PRESENT_PATH");
217+
return -1;
218+
}
219+
220+
if (getline(&line, &len, fp) == -1) {
221+
perror("Error reading CPU_PRESENT_PATH");
222+
fclose(fp);
223+
free(line);
224+
return -1;
225+
}
226+
fclose(fp);
227+
228+
token = strtok(line, ",");
229+
while (token) {
230+
if (sscanf(token, "%d-%d", &start, &end) == 2) {
231+
total_cpus += (end - start + 1);
232+
} else if (sscanf(token, "%d", &start) == 1) {
233+
total_cpus++;
234+
}
235+
token = strtok(NULL, ",");
236+
}
237+
238+
free(line);
239+
return total_cpus;
240+
}
241+
242+
int get_present_core_list(int **present_cores, int *num_present_cores, int threads_per_cpu)
243+
{
244+
FILE *fp = NULL;
245+
char *line = NULL;
246+
char *token = NULL;
247+
size_t len = 0;
248+
ssize_t read;
249+
int core_count = 0;
250+
int core_list_size;
251+
int *cores = NULL;
252+
int start, end, i;
253+
254+
if (threads_per_cpu <= 0) {
255+
fprintf(stderr, "Invalid threads_per_cpu value, got %d expected >= 1\n", threads_per_cpu);
256+
return -1;
257+
}
258+
259+
core_list_size = get_present_cpu_count() / threads_per_cpu;
260+
if (core_list_size <= 0) {
261+
fprintf(stderr, "Error while calculating core list size\n");
262+
return -1;
263+
}
264+
265+
cores = malloc(core_list_size * sizeof(int));
266+
if (!cores) {
267+
perror("Memory allocation failed");
268+
goto cleanup;
269+
}
270+
271+
fp = fopen(CPU_PRESENT_PATH, "r");
272+
if (!fp) {
273+
perror("Error opening file");
274+
goto cleanup;
275+
}
276+
277+
read = getline(&line, &len, fp);
278+
if (read == -1) {
279+
perror("Error reading file");
280+
goto cleanup;
281+
}
282+
283+
token = strtok(line, ",");
284+
while (token) {
285+
if (sscanf(token, "%d-%d", &start, &end) == 2) {
286+
for (i = start; i <= end; i++) {
287+
if (i % threads_per_cpu == 0) {
288+
cores[core_count++] = i / threads_per_cpu;
289+
}
290+
}
291+
} else if (sscanf(token, "%d", &start) == 1) {
292+
if (start % threads_per_cpu == 0) {
293+
cores[core_count++] = start / threads_per_cpu;
294+
}
295+
}
296+
token = strtok(NULL, ",");
297+
}
298+
299+
*present_cores = cores;
300+
*num_present_cores = core_count;
301+
free(line);
302+
return 0;
303+
304+
cleanup:
305+
if (fp) {
306+
fclose(fp);
307+
}
308+
free(line);
309+
free(cores);
310+
return -1;
311+
}
312+
206313
static void print_cpu_list(const cpu_set_t *cpuset, int cpuset_size,
207314
int cpus_in_system)
208315
{

src/common/cpu_info_helpers.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@
2424
#ifndef _CPU_INFO_HELPERS_H
2525
#define _CPU_INFO_HELPERS_H
2626

27-
#define SYSFS_CPUDIR "/sys/devices/system/cpu/cpu%d"
28-
#define SYSFS_SUBCORES "/sys/devices/system/cpu/subcores_per_core"
29-
#define INTSERV_PATH "/proc/device-tree/cpus/%s/ibm,ppc-interrupt-server#s"
27+
#define SYSFS_CPUDIR "/sys/devices/system/cpu/cpu%d"
28+
#define SYSFS_SUBCORES "/sys/devices/system/cpu/subcores_per_core"
29+
#define INTSERV_PATH "/proc/device-tree/cpus/%s/ibm,ppc-interrupt-server#s"
30+
#define CPU_PRESENT_PATH "/sys/devices/system/cpu/present"
3031

3132
#define SYSFS_PATH_MAX 128
3233

@@ -39,6 +40,8 @@ extern int num_subcores(void);
3940
extern int get_attribute(char *path, const char *fmt, int *value);
4041
extern int get_cpu_info(int *threads_per_cpu, int *cpus_in_system,
4142
int *threads_in_system);
43+
extern int get_present_core_list(int **present_cores, int *num_present_cores,
44+
int threads_per_cpu);
4245
extern int __is_smt_capable(int threads_in_system);
4346
extern int __get_one_smt_state(int core, int threads_per_cpu);
4447
extern int __do_smt(bool numeric, int cpus_in_system, int threads_per_cpu,

0 commit comments

Comments
 (0)