Loading tools/lib/bpf/libbpf.c +57 −0 Original line number Diff line number Diff line Loading @@ -3827,3 +3827,60 @@ void bpf_program__bpil_offs_to_addr(struct bpf_prog_info_linear *info_linear) desc->array_offset, addr); } } int libbpf_num_possible_cpus(void) { static const char *fcpu = "/sys/devices/system/cpu/possible"; int len = 0, n = 0, il = 0, ir = 0; unsigned int start = 0, end = 0; static int cpus; char buf[128]; int error = 0; int fd = -1; if (cpus > 0) return cpus; fd = open(fcpu, O_RDONLY); if (fd < 0) { error = errno; pr_warning("Failed to open file %s: %s\n", fcpu, strerror(error)); return -error; } len = read(fd, buf, sizeof(buf)); close(fd); if (len <= 0) { error = len ? errno : EINVAL; pr_warning("Failed to read # of possible cpus from %s: %s\n", fcpu, strerror(error)); return -error; } if (len == sizeof(buf)) { pr_warning("File %s size overflow\n", fcpu); return -EOVERFLOW; } buf[len] = '\0'; for (ir = 0, cpus = 0; ir <= len; ir++) { /* Each sub string separated by ',' has format \d+-\d+ or \d+ */ if (buf[ir] == ',' || buf[ir] == '\0') { buf[ir] = '\0'; n = sscanf(&buf[il], "%u-%u", &start, &end); if (n <= 0) { pr_warning("Failed to get # CPUs from %s\n", &buf[il]); return -EINVAL; } else if (n == 1) { end = start; } cpus += end - start + 1; il = ir + 1; } } if (cpus <= 0) { pr_warning("Invalid #CPUs %d from %s\n", cpus, fcpu); return -EINVAL; } return cpus; } tools/lib/bpf/libbpf.h +16 −0 Original line number Diff line number Diff line Loading @@ -454,6 +454,22 @@ bpf_program__bpil_addr_to_offs(struct bpf_prog_info_linear *info_linear); LIBBPF_API void bpf_program__bpil_offs_to_addr(struct bpf_prog_info_linear *info_linear); /* * A helper function to get the number of possible CPUs before looking up * per-CPU maps. Negative errno is returned on failure. * * Example usage: * * int ncpus = libbpf_num_possible_cpus(); * if (ncpus < 0) { * // error handling * } * long values[ncpus]; * bpf_map_lookup_elem(per_cpu_map_fd, key, values); * */ LIBBPF_API int libbpf_num_possible_cpus(void); #ifdef __cplusplus } /* extern "C" */ #endif Loading tools/lib/bpf/libbpf.map +1 −0 Original line number Diff line number Diff line Loading @@ -172,4 +172,5 @@ LIBBPF_0.0.4 { btf_dump__new; btf__parse_elf; bpf_object__load_xattr; libbpf_num_possible_cpus; } LIBBPF_0.0.3; Loading
tools/lib/bpf/libbpf.c +57 −0 Original line number Diff line number Diff line Loading @@ -3827,3 +3827,60 @@ void bpf_program__bpil_offs_to_addr(struct bpf_prog_info_linear *info_linear) desc->array_offset, addr); } } int libbpf_num_possible_cpus(void) { static const char *fcpu = "/sys/devices/system/cpu/possible"; int len = 0, n = 0, il = 0, ir = 0; unsigned int start = 0, end = 0; static int cpus; char buf[128]; int error = 0; int fd = -1; if (cpus > 0) return cpus; fd = open(fcpu, O_RDONLY); if (fd < 0) { error = errno; pr_warning("Failed to open file %s: %s\n", fcpu, strerror(error)); return -error; } len = read(fd, buf, sizeof(buf)); close(fd); if (len <= 0) { error = len ? errno : EINVAL; pr_warning("Failed to read # of possible cpus from %s: %s\n", fcpu, strerror(error)); return -error; } if (len == sizeof(buf)) { pr_warning("File %s size overflow\n", fcpu); return -EOVERFLOW; } buf[len] = '\0'; for (ir = 0, cpus = 0; ir <= len; ir++) { /* Each sub string separated by ',' has format \d+-\d+ or \d+ */ if (buf[ir] == ',' || buf[ir] == '\0') { buf[ir] = '\0'; n = sscanf(&buf[il], "%u-%u", &start, &end); if (n <= 0) { pr_warning("Failed to get # CPUs from %s\n", &buf[il]); return -EINVAL; } else if (n == 1) { end = start; } cpus += end - start + 1; il = ir + 1; } } if (cpus <= 0) { pr_warning("Invalid #CPUs %d from %s\n", cpus, fcpu); return -EINVAL; } return cpus; }
tools/lib/bpf/libbpf.h +16 −0 Original line number Diff line number Diff line Loading @@ -454,6 +454,22 @@ bpf_program__bpil_addr_to_offs(struct bpf_prog_info_linear *info_linear); LIBBPF_API void bpf_program__bpil_offs_to_addr(struct bpf_prog_info_linear *info_linear); /* * A helper function to get the number of possible CPUs before looking up * per-CPU maps. Negative errno is returned on failure. * * Example usage: * * int ncpus = libbpf_num_possible_cpus(); * if (ncpus < 0) { * // error handling * } * long values[ncpus]; * bpf_map_lookup_elem(per_cpu_map_fd, key, values); * */ LIBBPF_API int libbpf_num_possible_cpus(void); #ifdef __cplusplus } /* extern "C" */ #endif Loading
tools/lib/bpf/libbpf.map +1 −0 Original line number Diff line number Diff line Loading @@ -172,4 +172,5 @@ LIBBPF_0.0.4 { btf_dump__new; btf__parse_elf; bpf_object__load_xattr; libbpf_num_possible_cpus; } LIBBPF_0.0.3;