diff mbox series

Possible vs present number of cpus and propose for a new API function

Message ID 5fac42d2-f62e-0652-8d49-c348affbd432@gmail.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series Possible vs present number of cpus and propose for a new API function | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch
bpf/vmtest-bpf-PR fail merge-conflict

Commit Message

Carlos Rodriguez-Fernandez June 25, 2023, 2:56 p.m. UTC
Hi all,

The libbpf tool cpufreq uses the API function libbpf_num_possible_cpus 
to get the number of CPUs and then iterate over them to run its 
functionality, getting the information it needs from sysfs. The problem 
is that the cpu information in sysfs 
|/sys/devices/system/cpu/cpu##|appears only for the "present" cpus, not 
the "possible" in my system.

This is the error:

|failed to open 
'/sys/devices/system/cpu/cpu12/cpufreq/scaling_cur_freq': No such file 
or directory failed to init freqs My possible num of cpus: ||cat /sys/devices/system/cpu/possible 0-31 My present num of cpus: cat 
/sys/devices/system/cpu/present 0-11 For what I understand in the 
documentation here |https://www.kernel.org/doc/html/latest/admin-guide/cputopology.html, it 
should be using the "present" file. I submitted the bug here: 
https://bugzilla.redhat.com/show_bug.cgi?id=2217179 and here 
https://github.com/iovisor/bcc/issues/4651

Yesterday, I also ended up submitting a PR here:https://github.com/libbpf/libbpf/pull/701

The PR adds a new function calledlibbpf_num_present_cpus||||||  and refactors the existing one to reduce repeated code. My goal is to then provide a fix to cpufreq to use this new API function instead.

This morning I realized that I should have done it on this mailing list. Attached you can find the patch with this proposal. I can work towards a different proposal if preferred.

Thank you,
Carlos R.F.
diff mbox series

Patch

From fd2243bb096c05ca2c659c19522adadc88af348a Mon Sep 17 00:00:00 2001
From: Carlos Rodriguez-Fernandez <carlosrodrifernandez@gmail.com>
Date: Sat, 24 Jun 2023 22:41:34 -0700
Subject: [PATCH] libbpf: provide num present cpus

It allows tools to iterate over CPUs present
in the system that are actually running processes,
which can be less than the number of possible CPUs.

Signed-off-by: Carlos Rodriguez-Fernandez <carlosrodrifernandez@gmail.com>
---
 src/libbpf.c | 32 +++++++++++++++++++++++++++-----
 src/libbpf.h |  8 +++++---
 2 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/src/libbpf.c b/src/libbpf.c
index 214f828..e42d252 100644
--- a/src/libbpf.c
+++ b/src/libbpf.c
@@ -12615,14 +12615,26 @@  int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz)
 	return parse_cpu_mask_str(buf, mask, mask_sz);
 }
 
-int libbpf_num_possible_cpus(void)
+typedef enum {POSSIBLE=0, PRESENT, NUM_TYPES } CPU_TOPOLOGY_SYSFS_TYPE;
+
+static const char *cpu_topology_sysfs_path_by_type(const CPU_TOPOLOGY_SYSFS_TYPE type) {
+	const static char *possible_sysfs_path = "/sys/devices/system/cpu/possible";
+	const static char *present_sysfs_path = "/sys/devices/system/cpu/present";
+	switch(type) {
+		case POSSIBLE: return possible_sysfs_path;
+		case PRESENT: return present_sysfs_path;
+		default: return possible_sysfs_path;
+	}
+}
+
+int libbpf_num_cpus_by_topology_sysfs_type(const CPU_TOPOLOGY_SYSFS_TYPE type)
 {
-	static const char *fcpu = "/sys/devices/system/cpu/possible";
-	static int cpus;
+	const char *fcpu = cpu_topology_sysfs_path_by_type(type);
+	static int cpus[NUM_TYPES];
 	int err, n, i, tmp_cpus;
 	bool *mask;
 
-	tmp_cpus = READ_ONCE(cpus);
+	tmp_cpus = READ_ONCE(cpus[type]);
 	if (tmp_cpus > 0)
 		return tmp_cpus;
 
@@ -12637,10 +12649,20 @@  int libbpf_num_possible_cpus(void)
 	}
 	free(mask);
 
-	WRITE_ONCE(cpus, tmp_cpus);
+	WRITE_ONCE(cpus[type], tmp_cpus);
 	return tmp_cpus;
 }
 
+int libbpf_num_possible_cpus(void)
+{
+	return libbpf_num_cpus_by_topology_sysfs_type(POSSIBLE);
+}
+
+int libbpf_num_present_cpus(void)
+{
+	return libbpf_num_cpus_by_topology_sysfs_type(PRESENT);
+}
+
 static int populate_skeleton_maps(const struct bpf_object *obj,
 				  struct bpf_map_skeleton *maps,
 				  size_t map_cnt)
diff --git a/src/libbpf.h b/src/libbpf.h
index 754da73..a34152c 100644
--- a/src/libbpf.h
+++ b/src/libbpf.h
@@ -1433,9 +1433,10 @@  LIBBPF_API int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type,
 				       enum bpf_func_id helper_id, const void *opts);
 
 /**
- * @brief **libbpf_num_possible_cpus()** is a helper function to get the
- * number of possible CPUs that the host kernel supports and expects.
- * @return number of possible CPUs; or error code on failure
+ * @brief **libbpf_num_possible_cpus()**, and **libbpf_num_present_cpus()**
+ * are helper functions to get the number of possible, and present CPUs respectivelly.
+ * See for more information: https://www.kernel.org/doc/html/latest/admin-guide/cputopology.html
+ * @return number of CPUs; or error code on failure
  *
  * Example usage:
  *
@@ -1447,6 +1448,7 @@  LIBBPF_API int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type,
  *     bpf_map_lookup_elem(per_cpu_map_fd, key, values);
  */
 LIBBPF_API int libbpf_num_possible_cpus(void);
+LIBBPF_API int libbpf_num_present_cpus(void);
 
 struct bpf_map_skeleton {
 	const char *name;
-- 
2.41.0