From 022c64992af554cfd8c564bff86100fb5ed98678 Mon Sep 17 00:00:00 2001 From: Paul Moses Date: Tue, 20 Oct 2026 17:20:58 +0000 Subject: [PATCH] perf mmap: Use the head selected by read_init perf_mmap__push() reads the producer head before calling perf_mmap__read_init(), which reads it again to select the range to copy. If the producer advances between those reads, push() copies through the newer head but stores the earlier head in prev. The next drain starts at that earlier position and can write the same records to perf.data again. Use the head selected by read_init(): end for forward buffers and start for overwrite buffers. Save it before the copy loop advances start so prev matches the range that was copied. Fixes: 8872481bd04850b1 ("perf mmap: Introduce perf_mmap__read_init()") Signed-off-by: Paul Moses Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kan Liang Cc: Kan Liang Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/mmap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 358e70c4f3ed..6dcc4a9304b9 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -330,7 +330,7 @@ int mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, struct perf_cpu int perf_mmap__push(struct mmap *md, void *to, int push(struct mmap *map, void *to, void *buf, size_t size)) { - u64 head = perf_mmap__read_head(&md->core); + u64 head; unsigned char *data = md->core.base + page_size; unsigned long size; void *buf; @@ -340,6 +340,7 @@ int perf_mmap__push(struct mmap *md, void *to, if (rc < 0) return (rc == -EAGAIN) ? 1 : -1; + head = md->core.overwrite ? md->core.start : md->core.end; size = md->core.end - md->core.start; if ((md->core.start & md->core.mask) + size != (md->core.end & md->core.mask)) {