]> git.itanic.dy.fi Git - linux-stable/commitdiff
perf lock contention: Check race in tstamp elem creation
authorNamhyung Kim <namhyung@kernel.org>
Fri, 20 Oct 2023 20:47:40 +0000 (13:47 -0700)
committerNamhyung Kim <namhyung@kernel.org>
Wed, 25 Oct 2023 17:02:47 +0000 (10:02 -0700)
When pelem is NULL, it'd create a new entry with zero data.  But it
might be preempted by IRQ/NMI just before calling bpf_map_update_elem()
then there's a chance to call it twice for the same pid.  So it'd be
better to use BPF_NOEXIST flag and check the return value to prevent
the race.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Ian Rogers <irogers@google.com>
Cc: Hao Luo <haoluo@google.com>
Cc: Song Liu <song@kernel.org>
Cc: bpf@vger.kernel.org
Link: https://lore.kernel.org/r/20231020204741.1869520-2-namhyung@kernel.org
tools/perf/util/bpf_skel/lock_contention.bpf.c

index b11179452e19d8144e361503c7d0a0c868befb20..69d31fd77cd03843c8394c9e12a4af4b37d059a3 100644 (file)
@@ -328,7 +328,11 @@ int contention_begin(u64 *ctx)
        if (pelem == NULL) {
                struct tstamp_data zero = {};
 
-               bpf_map_update_elem(&tstamp, &pid, &zero, BPF_ANY);
+               if (bpf_map_update_elem(&tstamp, &pid, &zero, BPF_NOEXIST) < 0) {
+                       __sync_fetch_and_add(&task_fail, 1);
+                       return 0;
+               }
+
                pelem = bpf_map_lookup_elem(&tstamp, &pid);
                if (pelem == NULL) {
                        __sync_fetch_and_add(&task_fail, 1);