Takshak Chahande <ctaks...@fb.com> [Wed, 2019-07-31 15:11 -0700]: > Having static variable `cpus` in libbpf_num_possible_cpus function > without guarding it with mutex makes this function thread-unsafe. > > If multiple threads accessing this function, in the current form; it > leads to incrementing the static variable value `cpus` in the multiple > of total available CPUs. > > Used local stack variable to calculate the number of possible CPUs and > then updated the static variable using WRITE_ONCE(). > > Changes since v1: > * added stack variable to calculate cpus > * serialized static variable update using WRITE_ONCE() > * fixed Fixes tag
This "Changes" section should be after "---" line not to be included in the final commit message. Not sure if resubmit is needed because of it, but other than this looks good to me. Acked-by: Andrey Ignatov <r...@fb.com> > Fixes: 6446b3155521 ("bpf: add a new API libbpf_num_possible_cpus()") > Signed-off-by: Takshak Chahande <ctaks...@fb.com> > --- > tools/lib/bpf/libbpf.c | 18 +++++++++++------- > 1 file changed, 11 insertions(+), 7 deletions(-) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index 6718d0b90130..2e84fa5b8479 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -4995,13 +4995,15 @@ 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; > + int tmp_cpus = 0; > static int cpus; > char buf[128]; > int error = 0; > int fd = -1; > > - if (cpus > 0) > - return cpus; > + tmp_cpus = READ_ONCE(cpus); > + if (tmp_cpus > 0) > + return tmp_cpus; > > fd = open(fcpu, O_RDONLY); > if (fd < 0) { > @@ -5024,7 +5026,7 @@ int libbpf_num_possible_cpus(void) > } > buf[len] = '\0'; > > - for (ir = 0, cpus = 0; ir <= len; ir++) { > + for (ir = 0, tmp_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'; > @@ -5036,13 +5038,15 @@ int libbpf_num_possible_cpus(void) > } else if (n == 1) { > end = start; > } > - cpus += end - start + 1; > + tmp_cpus += end - start + 1; > il = ir + 1; > } > } > - if (cpus <= 0) { > - pr_warning("Invalid #CPUs %d from %s\n", cpus, fcpu); > + if (tmp_cpus <= 0) { > + pr_warning("Invalid #CPUs %d from %s\n", tmp_cpus, fcpu); > return -EINVAL; > } > - return cpus; > + > + WRITE_ONCE(cpus, tmp_cpus); > + return tmp_cpus; > } > -- > 2.17.1 > -- Andrey Ignatov