[tip:perf/core] perf tools: Fix compile error with libunwind x86
Commit-ID: 44df1afdb174fd6038e419f80efd914c0b5f2f85 Gitweb: https://git.kernel.org/tip/44df1afdb174fd6038e419f80efd914c0b5f2f85 Author: Wang Nan <wangn...@huawei.com> AuthorDate: Wed, 6 Dec 2017 01:50:40 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Mon, 8 Jan 2018 11:11:57 -0300 perf tools: Fix compile error with libunwind x86 Fix a compile error: ... CC util/libunwind/x86_32.o In file included from util/libunwind/x86_32.c:33:0: util/libunwind/../../arch/x86/util/unwind-libunwind.c: In function 'libunwind__x86_reg_id': util/libunwind/../../arch/x86/util/unwind-libunwind.c:110:11: error: 'EINVAL' undeclared (first use in this function) return -EINVAL; ^ util/libunwind/../../arch/x86/util/unwind-libunwind.c:110:11: note: each undeclared identifier is reported only once for each function it appears in mv: cannot stat 'util/libunwind/.x86_32.o.tmp': No such file or directory make[4]: *** [util/libunwind/x86_32.o] Error 1 make[3]: *** [util] Error 2 make[2]: *** [libperf-in.o] Error 2 make[1]: *** [sub-make] Error 2 make: *** [all] Error 2 It happens when libunwind-x86 feature is detected. Signed-off-by: Wang Nan <wangn...@huawei.com> Link: http://lkml.kernel.org/r/20171206015040.114574-1-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/arch/x86/util/unwind-libunwind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/arch/x86/util/unwind-libunwind.c b/tools/perf/arch/x86/util/unwind-libunwind.c index 9c917f8..05920e3 100644 --- a/tools/perf/arch/x86/util/unwind-libunwind.c +++ b/tools/perf/arch/x86/util/unwind-libunwind.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 -#ifndef REMOTE_UNWIND_LIBUNWIND #include +#ifndef REMOTE_UNWIND_LIBUNWIND #include #include "perf_regs.h" #include "../../util/unwind.h"
[tip:perf/core] perf tools: Fix compile error with libunwind x86
Commit-ID: 44df1afdb174fd6038e419f80efd914c0b5f2f85 Gitweb: https://git.kernel.org/tip/44df1afdb174fd6038e419f80efd914c0b5f2f85 Author: Wang Nan AuthorDate: Wed, 6 Dec 2017 01:50:40 + Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 8 Jan 2018 11:11:57 -0300 perf tools: Fix compile error with libunwind x86 Fix a compile error: ... CC util/libunwind/x86_32.o In file included from util/libunwind/x86_32.c:33:0: util/libunwind/../../arch/x86/util/unwind-libunwind.c: In function 'libunwind__x86_reg_id': util/libunwind/../../arch/x86/util/unwind-libunwind.c:110:11: error: 'EINVAL' undeclared (first use in this function) return -EINVAL; ^ util/libunwind/../../arch/x86/util/unwind-libunwind.c:110:11: note: each undeclared identifier is reported only once for each function it appears in mv: cannot stat 'util/libunwind/.x86_32.o.tmp': No such file or directory make[4]: *** [util/libunwind/x86_32.o] Error 1 make[3]: *** [util] Error 2 make[2]: *** [libperf-in.o] Error 2 make[1]: *** [sub-make] Error 2 make: *** [all] Error 2 It happens when libunwind-x86 feature is detected. Signed-off-by: Wang Nan Link: http://lkml.kernel.org/r/20171206015040.114574-1-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/unwind-libunwind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/arch/x86/util/unwind-libunwind.c b/tools/perf/arch/x86/util/unwind-libunwind.c index 9c917f8..05920e3 100644 --- a/tools/perf/arch/x86/util/unwind-libunwind.c +++ b/tools/perf/arch/x86/util/unwind-libunwind.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 -#ifndef REMOTE_UNWIND_LIBUNWIND #include +#ifndef REMOTE_UNWIND_LIBUNWIND #include #include "perf_regs.h" #include "../../util/unwind.h"
[RESEND PATCH] perf tools: Fix compiling error in libunwind x86
Fix a compiling error: ... CC util/libunwind/x86_32.o In file included from util/libunwind/x86_32.c:33:0: util/libunwind/../../arch/x86/util/unwind-libunwind.c: In function 'libunwind__x86_reg_id': util/libunwind/../../arch/x86/util/unwind-libunwind.c:110:11: error: 'EINVAL' undeclared (first use in this function) return -EINVAL; ^ util/libunwind/../../arch/x86/util/unwind-libunwind.c:110:11: note: each undeclared identifier is reported only once for each function it appears in mv: cannot stat 'util/libunwind/.x86_32.o.tmp': No such file or directory make[4]: *** [util/libunwind/x86_32.o] Error 1 make[3]: *** [util] Error 2 make[2]: *** [libperf-in.o] Error 2 make[1]: *** [sub-make] Error 2 make: *** [all] Error 2 It happens when libunwind-x86 feature is detected. Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Arnaldo Carvalho de Melo <a...@redhat.com> Cc: Jiri Olsa <jo...@redhat.com> --- tools/perf/arch/x86/util/unwind-libunwind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/arch/x86/util/unwind-libunwind.c b/tools/perf/arch/x86/util/unwind-libunwind.c index 9c917f8..05920e3 100644 --- a/tools/perf/arch/x86/util/unwind-libunwind.c +++ b/tools/perf/arch/x86/util/unwind-libunwind.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 -#ifndef REMOTE_UNWIND_LIBUNWIND #include +#ifndef REMOTE_UNWIND_LIBUNWIND #include #include "perf_regs.h" #include "../../util/unwind.h" -- 2.10.1
[RESEND PATCH] perf tools: Fix compiling error in libunwind x86
Fix a compiling error: ... CC util/libunwind/x86_32.o In file included from util/libunwind/x86_32.c:33:0: util/libunwind/../../arch/x86/util/unwind-libunwind.c: In function 'libunwind__x86_reg_id': util/libunwind/../../arch/x86/util/unwind-libunwind.c:110:11: error: 'EINVAL' undeclared (first use in this function) return -EINVAL; ^ util/libunwind/../../arch/x86/util/unwind-libunwind.c:110:11: note: each undeclared identifier is reported only once for each function it appears in mv: cannot stat 'util/libunwind/.x86_32.o.tmp': No such file or directory make[4]: *** [util/libunwind/x86_32.o] Error 1 make[3]: *** [util] Error 2 make[2]: *** [libperf-in.o] Error 2 make[1]: *** [sub-make] Error 2 make: *** [all] Error 2 It happens when libunwind-x86 feature is detected. Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa --- tools/perf/arch/x86/util/unwind-libunwind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/arch/x86/util/unwind-libunwind.c b/tools/perf/arch/x86/util/unwind-libunwind.c index 9c917f8..05920e3 100644 --- a/tools/perf/arch/x86/util/unwind-libunwind.c +++ b/tools/perf/arch/x86/util/unwind-libunwind.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 -#ifndef REMOTE_UNWIND_LIBUNWIND #include +#ifndef REMOTE_UNWIND_LIBUNWIND #include #include "perf_regs.h" #include "../../util/unwind.h" -- 2.10.1
[tip:perf/core] perf mmap: Don't discard prev in backward mode
Commit-ID: 7fb4b407a1242dbc85ea3ed1be065dca8f9a6f5b Gitweb: https://git.kernel.org/tip/7fb4b407a1242dbc85ea3ed1be065dca8f9a6f5b Author: Wang Nan <wangn...@huawei.com> AuthorDate: Mon, 4 Dec 2017 16:51:06 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Tue, 5 Dec 2017 15:59:37 -0300 perf mmap: Don't discard prev in backward mode 'perf record' can switch its output data file. The new output should only store the data after switching. However, in overwrite backward mode, the new output still can have data from before switching. That also brings extra overhead. At the end of mmap_read(), the position of the processed ring buffer is saved in md->prev. Next mmap_read should be end in md->prev if it is not overwriten. That avoids processing duplicate data. However, md->prev is discarded. So next the mmap_read() has to process whole valid ring buffer, which probably includes old processed data. Avoid calling backward_rb_find_range() when md->prev is still available. Signed-off-by: Wang Nan <wangn...@huawei.com> Tested-by: Kan Liang <kan.li...@intel.com> Acked-by: Namhyung Kim <namhy...@kernel.org> Cc: Jiri Olsa <jo...@redhat.com> Cc: Mengting Zhang <zhangmengt...@huawei.com> Link: http://lkml.kernel.org/r/20171204165107.95327-3-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/util/mmap.c | 33 +++-- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 3f262e7..5f8cb15 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -267,18 +267,6 @@ static int backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 return -1; } -static int rb_find_range(void *data, int mask, u64 head, u64 old, -u64 *start, u64 *end, bool backward) -{ - if (!backward) { - *start = old; - *end = head; - return 0; - } - - return backward_rb_find_range(data, mask, head, start, end); -} - int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)) { @@ -290,19 +278,28 @@ int perf_mmap__push(struct perf_mmap *md, bool backward, void *buf; int rc = 0; - if (rb_find_range(data, md->mask, head, old, , , backward)) - return -1; + start = backward ? head : old; + end = backward ? old : head; if (start == end) return 0; size = end - start; if (size > (unsigned long)(md->mask) + 1) { - WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); + if (!backward) { + WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); - md->prev = head; - perf_mmap__consume(md, backward); - return 0; + md->prev = head; + perf_mmap__consume(md, backward); + return 0; + } + + /* +* Backward ring buffer is full. We still have a chance to read +* most of data from it. +*/ + if (backward_rb_find_range(data, md->mask, head, , )) + return -1; } if ((start & md->mask) + size != (end & md->mask)) {
[tip:perf/core] perf mmap: Don't discard prev in backward mode
Commit-ID: 7fb4b407a1242dbc85ea3ed1be065dca8f9a6f5b Gitweb: https://git.kernel.org/tip/7fb4b407a1242dbc85ea3ed1be065dca8f9a6f5b Author: Wang Nan AuthorDate: Mon, 4 Dec 2017 16:51:06 + Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 5 Dec 2017 15:59:37 -0300 perf mmap: Don't discard prev in backward mode 'perf record' can switch its output data file. The new output should only store the data after switching. However, in overwrite backward mode, the new output still can have data from before switching. That also brings extra overhead. At the end of mmap_read(), the position of the processed ring buffer is saved in md->prev. Next mmap_read should be end in md->prev if it is not overwriten. That avoids processing duplicate data. However, md->prev is discarded. So next the mmap_read() has to process whole valid ring buffer, which probably includes old processed data. Avoid calling backward_rb_find_range() when md->prev is still available. Signed-off-by: Wang Nan Tested-by: Kan Liang Acked-by: Namhyung Kim Cc: Jiri Olsa Cc: Mengting Zhang Link: http://lkml.kernel.org/r/20171204165107.95327-3-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/mmap.c | 33 +++-- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 3f262e7..5f8cb15 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -267,18 +267,6 @@ static int backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 return -1; } -static int rb_find_range(void *data, int mask, u64 head, u64 old, -u64 *start, u64 *end, bool backward) -{ - if (!backward) { - *start = old; - *end = head; - return 0; - } - - return backward_rb_find_range(data, mask, head, start, end); -} - int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)) { @@ -290,19 +278,28 @@ int perf_mmap__push(struct perf_mmap *md, bool backward, void *buf; int rc = 0; - if (rb_find_range(data, md->mask, head, old, , , backward)) - return -1; + start = backward ? head : old; + end = backward ? old : head; if (start == end) return 0; size = end - start; if (size > (unsigned long)(md->mask) + 1) { - WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); + if (!backward) { + WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); - md->prev = head; - perf_mmap__consume(md, backward); - return 0; + md->prev = head; + perf_mmap__consume(md, backward); + return 0; + } + + /* +* Backward ring buffer is full. We still have a chance to read +* most of data from it. +*/ + if (backward_rb_find_range(data, md->mask, head, , )) + return -1; } if ((start & md->mask) + size != (end & md->mask)) {
[tip:perf/core] perf tools: Rename 'backward' to 'overwrite' in evlist, mmap and record
Commit-ID: 0b72d69a542873ee098867deeb37d27ad4629c64 Gitweb: https://git.kernel.org/tip/0b72d69a542873ee098867deeb37d27ad4629c64 Author: Wang Nan <wangn...@huawei.com> AuthorDate: Mon, 4 Dec 2017 16:51:07 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Tue, 5 Dec 2017 16:02:39 -0300 perf tools: Rename 'backward' to 'overwrite' in evlist, mmap and record Remove the backward/forward concept to make it uniform with user interface (the '--overwrite' option). Signed-off-by: Wang Nan <wangn...@huawei.com> Acked-by: Namhyung Kim <namhy...@kernel.org> Cc: Jiri Olsa <jo...@redhat.com> Cc: Kan Liang <kan.li...@intel.com> Cc: Mengting Zhang <zhangmengt...@huawei.com> Link: http://lkml.kernel.org/r/20171204165107.95327-4-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/builtin-record.c | 14 +++--- tools/perf/tests/backward-ring-buffer.c | 4 ++-- tools/perf/util/evlist.c| 30 +++--- tools/perf/util/evlist.h| 2 +- tools/perf/util/mmap.c | 22 +++--- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 26b8571..0a5749e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -479,7 +479,7 @@ static struct perf_event_header finished_round_event = { }; static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist, - bool backward) + bool overwrite) { u64 bytes_written = rec->bytes_written; int i; @@ -489,18 +489,18 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli if (!evlist) return 0; - maps = backward ? evlist->backward_mmap : evlist->mmap; + maps = overwrite ? evlist->overwrite_mmap : evlist->mmap; if (!maps) return 0; - if (backward && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) + if (overwrite && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) return 0; for (i = 0; i < evlist->nr_mmaps; i++) { struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], overwrite, rec, record__pushfn) != 0) { rc = -1; goto out; } @@ -520,7 +520,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli if (bytes_written != rec->bytes_written) rc = record__write(rec, _round_event, sizeof(finished_round_event)); - if (backward) + if (overwrite) perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY); out: return rc; @@ -692,8 +692,8 @@ perf_evlist__pick_pc(struct perf_evlist *evlist) if (evlist) { if (evlist->mmap && evlist->mmap[0].base) return evlist->mmap[0].base; - if (evlist->backward_mmap && evlist->backward_mmap[0].base) - return evlist->backward_mmap[0].base; + if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].base) + return evlist->overwrite_mmap[0].base; } return NULL; } diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index cf37e43..4035d43 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -33,8 +33,8 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; - perf_mmap__read_catchup(>backward_mmap[i]); - while ((event = perf_mmap__read_backward(>backward_mmap[i])) != NULL) { + perf_mmap__read_catchup(>overwrite_mmap[i]); + while ((event = perf_mmap__read_backward(>overwrite_mmap[i])) != NULL) { const u32 type = event->header.type; switch (type) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index b1cea71..3570355 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -125,7 +125,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist) void perf_evlist__exit(struct perf_evlist *evlist) { zfree(>mmap); - zfree(>backward_mmap); + zfree(>overwrite_mmap); fdarray__exit(>pollfd); } @@ -675,11 +675,11 @@ static int perf_evlist__set_paused(struc
[tip:perf/core] perf tools: Rename 'backward' to 'overwrite' in evlist, mmap and record
Commit-ID: 0b72d69a542873ee098867deeb37d27ad4629c64 Gitweb: https://git.kernel.org/tip/0b72d69a542873ee098867deeb37d27ad4629c64 Author: Wang Nan AuthorDate: Mon, 4 Dec 2017 16:51:07 + Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 5 Dec 2017 16:02:39 -0300 perf tools: Rename 'backward' to 'overwrite' in evlist, mmap and record Remove the backward/forward concept to make it uniform with user interface (the '--overwrite' option). Signed-off-by: Wang Nan Acked-by: Namhyung Kim Cc: Jiri Olsa Cc: Kan Liang Cc: Mengting Zhang Link: http://lkml.kernel.org/r/20171204165107.95327-4-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 14 +++--- tools/perf/tests/backward-ring-buffer.c | 4 ++-- tools/perf/util/evlist.c| 30 +++--- tools/perf/util/evlist.h| 2 +- tools/perf/util/mmap.c | 22 +++--- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 26b8571..0a5749e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -479,7 +479,7 @@ static struct perf_event_header finished_round_event = { }; static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist, - bool backward) + bool overwrite) { u64 bytes_written = rec->bytes_written; int i; @@ -489,18 +489,18 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli if (!evlist) return 0; - maps = backward ? evlist->backward_mmap : evlist->mmap; + maps = overwrite ? evlist->overwrite_mmap : evlist->mmap; if (!maps) return 0; - if (backward && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) + if (overwrite && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) return 0; for (i = 0; i < evlist->nr_mmaps; i++) { struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], overwrite, rec, record__pushfn) != 0) { rc = -1; goto out; } @@ -520,7 +520,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli if (bytes_written != rec->bytes_written) rc = record__write(rec, _round_event, sizeof(finished_round_event)); - if (backward) + if (overwrite) perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY); out: return rc; @@ -692,8 +692,8 @@ perf_evlist__pick_pc(struct perf_evlist *evlist) if (evlist) { if (evlist->mmap && evlist->mmap[0].base) return evlist->mmap[0].base; - if (evlist->backward_mmap && evlist->backward_mmap[0].base) - return evlist->backward_mmap[0].base; + if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].base) + return evlist->overwrite_mmap[0].base; } return NULL; } diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index cf37e43..4035d43 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -33,8 +33,8 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; - perf_mmap__read_catchup(>backward_mmap[i]); - while ((event = perf_mmap__read_backward(>backward_mmap[i])) != NULL) { + perf_mmap__read_catchup(>overwrite_mmap[i]); + while ((event = perf_mmap__read_backward(>overwrite_mmap[i])) != NULL) { const u32 type = event->header.type; switch (type) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index b1cea71..3570355 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -125,7 +125,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist) void perf_evlist__exit(struct perf_evlist *evlist) { zfree(>mmap); - zfree(>backward_mmap); + zfree(>overwrite_mmap); fdarray__exit(>pollfd); } @@ -675,11 +675,11 @@ static int perf_evlist__set_paused(struct perf_evlist *evlist, bool value) { int i; - if (!evlist->backward_mmap) + if (!evlist->overwrite_mmap) return 0; for (i = 0; i < evlist->nr_mmap
[tip:perf/core] perf mmap: Fix perf backward recording
Commit-ID: 71f566a34986f4a86a8c546c7a36f70f0132b8a9 Gitweb: https://git.kernel.org/tip/71f566a34986f4a86a8c546c7a36f70f0132b8a9 Author: Wang Nan <wangn...@huawei.com> AuthorDate: Mon, 4 Dec 2017 16:51:05 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Tue, 5 Dec 2017 15:45:36 -0300 perf mmap: Fix perf backward recording 'perf record' backward recording doesn't work as we expected: it never overwrites when ring buffer gets full. Test: Run a busy python printing task background like this: while True: print 123 send SIGUSR2 to perf to capture snapshot, then: # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101520743 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521251 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521692 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101521936 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101520743 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521251 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521692 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 Timestamps never change, but my background task is a dead loop, can easily overwhelm the ring buffer. This patch fixes it by forcing unsetting PROT_WRITE for a backward ring buffer, so all backward ring buffers become overwrite ring buffers. Test result: # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101285323 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290053 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290446 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101290837 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101285323 | head -n3 python 2545 [000] 11064.268083: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11064.268084: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11064.268086: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101290 | head -n3 failed to open ./perf.data.2017110101290: No such file or directory # ./perf script -i ./perf.data.2017110101290053 | head -n3 python 2545 [000] 11071.564062: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11071.564064: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11071.564066: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) # ./perf script -i ./perf.data.2017110101290 | head -n3 perf.data.2017110101290053 perf.data.2017110101290446 perf.data.2017110101290837 # ./perf script -i ./perf.data.2017110101290446 | head -n3 sshd 1321 [000] 11075.499473: raw_syscalls:sys_exit: NR 14 = 0 sshd 1321 [000] 11075.499474: raw_syscalls:sys_enter: NR 14 (2, 7ffe98899490, 0, 8, 0, 3000) sshd 1321 [000] 11075.499474: raw_syscalls:sys_exit: NR 14 = 0 # ./perf script -i ./perf.data.2017110101290837 | head -n3 python 2545 [000] 11079.280844: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11079.280847: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11079.280850: raw_syscalls:sys_exit: NR 1 = 4 Signed-off-by: Wang Nan <wangn...@huawei.com> Acked-by: Namhyung Kim <namhy...@kernel.org> Cc: Jiri Olsa <jo...@redhat.com> Cc: Kan Liang <kan.li...@intel.com> Cc: Mengting Zhang <zhangmengt...@huawei.com> Link: http://lkml.kernel.org/r/20171204165107.95327-2-
[tip:perf/core] perf mmap: Fix perf backward recording
Commit-ID: 71f566a34986f4a86a8c546c7a36f70f0132b8a9 Gitweb: https://git.kernel.org/tip/71f566a34986f4a86a8c546c7a36f70f0132b8a9 Author: Wang Nan AuthorDate: Mon, 4 Dec 2017 16:51:05 + Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 5 Dec 2017 15:45:36 -0300 perf mmap: Fix perf backward recording 'perf record' backward recording doesn't work as we expected: it never overwrites when ring buffer gets full. Test: Run a busy python printing task background like this: while True: print 123 send SIGUSR2 to perf to capture snapshot, then: # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101520743 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521251 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521692 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101521936 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101520743 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521251 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521692 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 Timestamps never change, but my background task is a dead loop, can easily overwhelm the ring buffer. This patch fixes it by forcing unsetting PROT_WRITE for a backward ring buffer, so all backward ring buffers become overwrite ring buffers. Test result: # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101285323 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290053 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290446 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101290837 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101285323 | head -n3 python 2545 [000] 11064.268083: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11064.268084: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11064.268086: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101290 | head -n3 failed to open ./perf.data.2017110101290: No such file or directory # ./perf script -i ./perf.data.2017110101290053 | head -n3 python 2545 [000] 11071.564062: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11071.564064: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11071.564066: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) # ./perf script -i ./perf.data.2017110101290 | head -n3 perf.data.2017110101290053 perf.data.2017110101290446 perf.data.2017110101290837 # ./perf script -i ./perf.data.2017110101290446 | head -n3 sshd 1321 [000] 11075.499473: raw_syscalls:sys_exit: NR 14 = 0 sshd 1321 [000] 11075.499474: raw_syscalls:sys_enter: NR 14 (2, 7ffe98899490, 0, 8, 0, 3000) sshd 1321 [000] 11075.499474: raw_syscalls:sys_exit: NR 14 = 0 # ./perf script -i ./perf.data.2017110101290837 | head -n3 python 2545 [000] 11079.280844: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11079.280847: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11079.280850: raw_syscalls:sys_exit: NR 1 = 4 Signed-off-by: Wang Nan Acked-by: Namhyung Kim Cc: Jiri Olsa Cc: Kan Liang Cc: Mengting Zhang Link: http://lkml.kernel.org/r/20171204165107.95327-2-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/perf/util
[tip:perf/core] perf mmap: Remove overwrite and check_messup from mmap read
Commit-ID: 8eb7a1fe31612fd3e8ae8042dd2ebaf7575504cb Gitweb: https://git.kernel.org/tip/8eb7a1fe31612fd3e8ae8042dd2ebaf7575504cb Author: Wang Nan <wangn...@huawei.com> AuthorDate: Sun, 3 Dec 2017 02:00:41 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Tue, 5 Dec 2017 15:43:54 -0300 perf mmap: Remove overwrite and check_messup from mmap read All perf_mmap__read_forward() read from read-write ring buffer, so no need check_messup. Reading from backward ring buffer doesn't require check_messup because it never mess up. Cleanup arguments lists. Signed-off-by: Wang Nan <wangn...@huawei.com> Acked-by: Namhyung Kim <namhy...@kernel.org> Cc: Jiri Olsa <jo...@redhat.com> Cc: Kan Liang <kan.li...@intel.com> Link: http://lkml.kernel.org/r/20171203020044.81680-6-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/util/evlist.c | 2 +- tools/perf/util/mmap.c | 28 tools/perf/util/mmap.h | 2 +- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index a59134f..68c1f95 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -711,7 +711,7 @@ union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int * No need for read-write ring buffer: kernel stop outputting when * it hit md->prev (perf_mmap__consume()). */ - return perf_mmap__read_forward(md, false); + return perf_mmap__read_forward(md); } union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 703ed41..3f262e7 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -21,33 +21,13 @@ size_t perf_mmap__mmap_len(struct perf_mmap *map) } /* When check_messup is true, 'end' must points to a good entry */ -static union perf_event *perf_mmap__read(struct perf_mmap *map, bool check_messup, +static union perf_event *perf_mmap__read(struct perf_mmap *map, u64 start, u64 end, u64 *prev) { unsigned char *data = map->base + page_size; union perf_event *event = NULL; int diff = end - start; - if (check_messup) { - /* -* If we're further behind than half the buffer, there's a chance -* the writer will bite our tail and mess up the samples under us. -* -* If we somehow ended up ahead of the 'end', we got messed up. -* -* In either case, truncate and restart at 'end'. -*/ - if (diff > map->mask / 2 || diff < 0) { - fprintf(stderr, "WARNING: failed to keep up with mmap data.\n"); - - /* -* 'end' points to a known good entry, start there. -*/ - start = end; - diff = 0; - } - } - if (diff >= (int)sizeof(event->header)) { size_t size; @@ -89,7 +69,7 @@ broken_event: return event; } -union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup) +union perf_event *perf_mmap__read_forward(struct perf_mmap *map) { u64 head; u64 old = map->prev; @@ -102,7 +82,7 @@ union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_mess head = perf_mmap__read_head(map); - return perf_mmap__read(map, check_messup, old, head, >prev); + return perf_mmap__read(map, old, head, >prev); } union perf_event *perf_mmap__read_backward(struct perf_mmap *map) @@ -138,7 +118,7 @@ union perf_event *perf_mmap__read_backward(struct perf_mmap *map) else end = head + map->mask + 1; - return perf_mmap__read(map, false, start, end, >prev); + return perf_mmap__read(map, start, end, >prev); } void perf_mmap__read_catchup(struct perf_mmap *map) diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 2c3d291..d640273 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -86,7 +86,7 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) pc->data_tail = tail; } -union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup); +union perf_event *perf_mmap__read_forward(struct perf_mmap *map); union perf_event *perf_mmap__read_backward(struct perf_mmap *map); int perf_mmap__push(struct perf_mmap *md, bool backward,
[tip:perf/core] perf mmap: Remove overwrite and check_messup from mmap read
Commit-ID: 8eb7a1fe31612fd3e8ae8042dd2ebaf7575504cb Gitweb: https://git.kernel.org/tip/8eb7a1fe31612fd3e8ae8042dd2ebaf7575504cb Author: Wang Nan AuthorDate: Sun, 3 Dec 2017 02:00:41 + Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 5 Dec 2017 15:43:54 -0300 perf mmap: Remove overwrite and check_messup from mmap read All perf_mmap__read_forward() read from read-write ring buffer, so no need check_messup. Reading from backward ring buffer doesn't require check_messup because it never mess up. Cleanup arguments lists. Signed-off-by: Wang Nan Acked-by: Namhyung Kim Cc: Jiri Olsa Cc: Kan Liang Link: http://lkml.kernel.org/r/20171203020044.81680-6-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 2 +- tools/perf/util/mmap.c | 28 tools/perf/util/mmap.h | 2 +- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index a59134f..68c1f95 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -711,7 +711,7 @@ union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int * No need for read-write ring buffer: kernel stop outputting when * it hit md->prev (perf_mmap__consume()). */ - return perf_mmap__read_forward(md, false); + return perf_mmap__read_forward(md); } union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 703ed41..3f262e7 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -21,33 +21,13 @@ size_t perf_mmap__mmap_len(struct perf_mmap *map) } /* When check_messup is true, 'end' must points to a good entry */ -static union perf_event *perf_mmap__read(struct perf_mmap *map, bool check_messup, +static union perf_event *perf_mmap__read(struct perf_mmap *map, u64 start, u64 end, u64 *prev) { unsigned char *data = map->base + page_size; union perf_event *event = NULL; int diff = end - start; - if (check_messup) { - /* -* If we're further behind than half the buffer, there's a chance -* the writer will bite our tail and mess up the samples under us. -* -* If we somehow ended up ahead of the 'end', we got messed up. -* -* In either case, truncate and restart at 'end'. -*/ - if (diff > map->mask / 2 || diff < 0) { - fprintf(stderr, "WARNING: failed to keep up with mmap data.\n"); - - /* -* 'end' points to a known good entry, start there. -*/ - start = end; - diff = 0; - } - } - if (diff >= (int)sizeof(event->header)) { size_t size; @@ -89,7 +69,7 @@ broken_event: return event; } -union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup) +union perf_event *perf_mmap__read_forward(struct perf_mmap *map) { u64 head; u64 old = map->prev; @@ -102,7 +82,7 @@ union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_mess head = perf_mmap__read_head(map); - return perf_mmap__read(map, check_messup, old, head, >prev); + return perf_mmap__read(map, old, head, >prev); } union perf_event *perf_mmap__read_backward(struct perf_mmap *map) @@ -138,7 +118,7 @@ union perf_event *perf_mmap__read_backward(struct perf_mmap *map) else end = head + map->mask + 1; - return perf_mmap__read(map, false, start, end, >prev); + return perf_mmap__read(map, start, end, >prev); } void perf_mmap__read_catchup(struct perf_mmap *map) diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 2c3d291..d640273 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -86,7 +86,7 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) pc->data_tail = tail; } -union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup); +union perf_event *perf_mmap__read_forward(struct perf_mmap *map); union perf_event *perf_mmap__read_backward(struct perf_mmap *map); int perf_mmap__push(struct perf_mmap *md, bool backward,
[tip:perf/core] perf mmap: Remove overwrite from arguments list of perf_mmap__push
Commit-ID: ca6a9a05391960be5e8161a59a9854b32325d901 Gitweb: https://git.kernel.org/tip/ca6a9a05391960be5e8161a59a9854b32325d901 Author: Wang Nan <wangn...@huawei.com> AuthorDate: Sun, 3 Dec 2017 02:00:40 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Tue, 5 Dec 2017 15:43:54 -0300 perf mmap: Remove overwrite from arguments list of perf_mmap__push 'overwrite' argument is always 'false'. Remove it from arguments list of perf_mmap__push(). Signed-off-by: Wang Nan <wangn...@huawei.com> Acked-by: Namhyung Kim <namhy...@kernel.org> Cc: Jiri Olsa <jo...@redhat.com> Cc: Kan Liang <kan.li...@intel.com> Link: http://lkml.kernel.org/r/20171203020044.81680-5-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/builtin-record.c | 2 +- tools/perf/util/mmap.c | 6 +++--- tools/perf/util/mmap.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 3bc6cee..26b8571 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -500,7 +500,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], false, backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], backward, rec, record__pushfn) != 0) { rc = -1; goto out; } diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 9fe5f9c..703ed41 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -299,7 +299,7 @@ static int rb_find_range(void *data, int mask, u64 head, u64 old, return backward_rb_find_range(data, mask, head, start, end); } -int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, +int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)) { u64 head = perf_mmap__read_head(md); @@ -321,7 +321,7 @@ int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); md->prev = head; - perf_mmap__consume(md, overwrite || backward); + perf_mmap__consume(md, backward); return 0; } @@ -346,7 +346,7 @@ int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, } md->prev = head; - perf_mmap__consume(md, overwrite || backward); + perf_mmap__consume(md, backward); out: return rc; } diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index efd78b8..2c3d291 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -89,7 +89,7 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup); union perf_event *perf_mmap__read_backward(struct perf_mmap *map); -int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, +int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)); size_t perf_mmap__mmap_len(struct perf_mmap *map);
[tip:perf/core] perf mmap: Remove overwrite from arguments list of perf_mmap__push
Commit-ID: ca6a9a05391960be5e8161a59a9854b32325d901 Gitweb: https://git.kernel.org/tip/ca6a9a05391960be5e8161a59a9854b32325d901 Author: Wang Nan AuthorDate: Sun, 3 Dec 2017 02:00:40 + Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 5 Dec 2017 15:43:54 -0300 perf mmap: Remove overwrite from arguments list of perf_mmap__push 'overwrite' argument is always 'false'. Remove it from arguments list of perf_mmap__push(). Signed-off-by: Wang Nan Acked-by: Namhyung Kim Cc: Jiri Olsa Cc: Kan Liang Link: http://lkml.kernel.org/r/20171203020044.81680-5-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 2 +- tools/perf/util/mmap.c | 6 +++--- tools/perf/util/mmap.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 3bc6cee..26b8571 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -500,7 +500,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], false, backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], backward, rec, record__pushfn) != 0) { rc = -1; goto out; } diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 9fe5f9c..703ed41 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -299,7 +299,7 @@ static int rb_find_range(void *data, int mask, u64 head, u64 old, return backward_rb_find_range(data, mask, head, start, end); } -int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, +int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)) { u64 head = perf_mmap__read_head(md); @@ -321,7 +321,7 @@ int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); md->prev = head; - perf_mmap__consume(md, overwrite || backward); + perf_mmap__consume(md, backward); return 0; } @@ -346,7 +346,7 @@ int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, } md->prev = head; - perf_mmap__consume(md, overwrite || backward); + perf_mmap__consume(md, backward); out: return rc; } diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index efd78b8..2c3d291 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -89,7 +89,7 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup); union perf_event *perf_mmap__read_backward(struct perf_mmap *map); -int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, +int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)); size_t perf_mmap__mmap_len(struct perf_mmap *map);
[tip:perf/core] perf evlist: Remove evlist->overwrite
Commit-ID: 144b9a4fc53039c09007b71a06640560a6e62140 Gitweb: https://git.kernel.org/tip/144b9a4fc53039c09007b71a06640560a6e62140 Author: Wang Nan <wangn...@huawei.com> AuthorDate: Sun, 3 Dec 2017 02:00:39 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Tue, 5 Dec 2017 15:43:54 -0300 perf evlist: Remove evlist->overwrite evlist->overwrite is set to false in all users. It can be removed. Signed-off-by: Wang Nan <wangn...@huawei.com> Acked-by: Namhyung Kim <namhy...@kernel.org> Cc: Jiri Olsa <jo...@redhat.com> Cc: Kan Liang <kan.li...@intel.com> Link: http://lkml.kernel.org/r/20171203020044.81680-4-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/builtin-record.c | 2 +- tools/perf/util/evlist.c| 5 ++--- tools/perf/util/evlist.h| 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 08070f8..3bc6cee 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -500,7 +500,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], evlist->overwrite, backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], false, backward, rec, record__pushfn) != 0) { rc = -1; goto out; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 93272d9..a59134f 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -711,7 +711,7 @@ union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int * No need for read-write ring buffer: kernel stop outputting when * it hit md->prev (perf_mmap__consume()). */ - return perf_mmap__read_forward(md, evlist->overwrite); + return perf_mmap__read_forward(md, false); } union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx) @@ -738,7 +738,7 @@ void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx) void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx) { - perf_mmap__consume(>mmap[idx], evlist->overwrite); + perf_mmap__consume(>mmap[idx], false); } static void perf_evlist__munmap_nofree(struct perf_evlist *evlist) @@ -1070,7 +1070,6 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) return -ENOMEM; - evlist->overwrite = false; evlist->mmap_len = perf_evlist__mmap_size(pages); pr_debug("mmap size %zuB\n", evlist->mmap_len); mp.mask = evlist->mmap_len - page_size - 1; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 424a3d6..eec3377 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -31,7 +31,6 @@ struct perf_evlist { int nr_entries; int nr_groups; int nr_mmaps; - bool overwrite; bool enabled; bool has_user_cpus; size_t mmap_len;
[tip:perf/core] perf evlist: Remove evlist->overwrite
Commit-ID: 144b9a4fc53039c09007b71a06640560a6e62140 Gitweb: https://git.kernel.org/tip/144b9a4fc53039c09007b71a06640560a6e62140 Author: Wang Nan AuthorDate: Sun, 3 Dec 2017 02:00:39 + Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 5 Dec 2017 15:43:54 -0300 perf evlist: Remove evlist->overwrite evlist->overwrite is set to false in all users. It can be removed. Signed-off-by: Wang Nan Acked-by: Namhyung Kim Cc: Jiri Olsa Cc: Kan Liang Link: http://lkml.kernel.org/r/20171203020044.81680-4-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 2 +- tools/perf/util/evlist.c| 5 ++--- tools/perf/util/evlist.h| 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 08070f8..3bc6cee 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -500,7 +500,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], evlist->overwrite, backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], false, backward, rec, record__pushfn) != 0) { rc = -1; goto out; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 93272d9..a59134f 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -711,7 +711,7 @@ union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int * No need for read-write ring buffer: kernel stop outputting when * it hit md->prev (perf_mmap__consume()). */ - return perf_mmap__read_forward(md, evlist->overwrite); + return perf_mmap__read_forward(md, false); } union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx) @@ -738,7 +738,7 @@ void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx) void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx) { - perf_mmap__consume(>mmap[idx], evlist->overwrite); + perf_mmap__consume(>mmap[idx], false); } static void perf_evlist__munmap_nofree(struct perf_evlist *evlist) @@ -1070,7 +1070,6 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) return -ENOMEM; - evlist->overwrite = false; evlist->mmap_len = perf_evlist__mmap_size(pages); pr_debug("mmap size %zuB\n", evlist->mmap_len); mp.mask = evlist->mmap_len - page_size - 1; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 424a3d6..eec3377 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -31,7 +31,6 @@ struct perf_evlist { int nr_entries; int nr_groups; int nr_mmaps; - bool overwrite; bool enabled; bool has_user_cpus; size_t mmap_len;
[tip:perf/core] perf evlist: Remove 'overwrite' parameter from perf_evlist__mmap_ex
Commit-ID: 7a276ff6c3202697c3c15cad757dec3bb07d14bf Gitweb: https://git.kernel.org/tip/7a276ff6c3202697c3c15cad757dec3bb07d14bf Author: Wang Nan <wangn...@huawei.com> AuthorDate: Sun, 3 Dec 2017 02:00:38 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Tue, 5 Dec 2017 15:43:53 -0300 perf evlist: Remove 'overwrite' parameter from perf_evlist__mmap_ex All users of perf_evlist__mmap_ex set !overwrite. Remove it from its arguments list. Signed-off-by: Wang Nan <wangn...@huawei.com> Acked-by: Namhyung Kim <namhy...@kernel.org> Cc: Jiri Olsa <jo...@redhat.com> Cc: Kan Liang <kan.li...@intel.com> Link: http://lkml.kernel.org/r/20171203020044.81680-3-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/builtin-record.c | 2 +- tools/perf/util/evlist.c| 8 tools/perf/util/evlist.h| 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e304bc4..08070f8 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -301,7 +301,7 @@ static int record__mmap_evlist(struct record *rec, struct record_opts *opts = >opts; char msg[512]; - if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, + if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, opts->auxtrace_mmap_pages, opts->auxtrace_snapshot_mode) < 0) { if (errno == EPERM) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 3c1778b..93272d9 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1052,14 +1052,14 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, * Return: %0 on success, negative error code otherwise. */ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, -bool overwrite, unsigned int auxtrace_pages, +unsigned int auxtrace_pages, bool auxtrace_overwrite) { struct perf_evsel *evsel; const struct cpu_map *cpus = evlist->cpus; const struct thread_map *threads = evlist->threads; struct mmap_params mp = { - .prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), + .prot = PROT_READ | PROT_WRITE, }; if (!evlist->mmap) @@ -1070,7 +1070,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) return -ENOMEM; - evlist->overwrite = overwrite; + evlist->overwrite = false; evlist->mmap_len = perf_evlist__mmap_size(pages); pr_debug("mmap size %zuB\n", evlist->mmap_len); mp.mask = evlist->mmap_len - page_size - 1; @@ -1093,7 +1093,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages) { - return perf_evlist__mmap_ex(evlist, pages, false, 0, false); + return perf_evlist__mmap_ex(evlist, pages, 0, false); } int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index f0f2c8b..424a3d6 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -169,7 +169,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, unsigned long perf_event_mlock_kb_in_pages(void); int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, -bool overwrite, unsigned int auxtrace_pages, +unsigned int auxtrace_pages, bool auxtrace_overwrite); int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages); void perf_evlist__munmap(struct perf_evlist *evlist);
[tip:perf/core] perf evlist: Remove 'overwrite' parameter from perf_evlist__mmap_ex
Commit-ID: 7a276ff6c3202697c3c15cad757dec3bb07d14bf Gitweb: https://git.kernel.org/tip/7a276ff6c3202697c3c15cad757dec3bb07d14bf Author: Wang Nan AuthorDate: Sun, 3 Dec 2017 02:00:38 + Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 5 Dec 2017 15:43:53 -0300 perf evlist: Remove 'overwrite' parameter from perf_evlist__mmap_ex All users of perf_evlist__mmap_ex set !overwrite. Remove it from its arguments list. Signed-off-by: Wang Nan Acked-by: Namhyung Kim Cc: Jiri Olsa Cc: Kan Liang Link: http://lkml.kernel.org/r/20171203020044.81680-3-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 2 +- tools/perf/util/evlist.c| 8 tools/perf/util/evlist.h| 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e304bc4..08070f8 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -301,7 +301,7 @@ static int record__mmap_evlist(struct record *rec, struct record_opts *opts = >opts; char msg[512]; - if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, + if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, opts->auxtrace_mmap_pages, opts->auxtrace_snapshot_mode) < 0) { if (errno == EPERM) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 3c1778b..93272d9 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1052,14 +1052,14 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, * Return: %0 on success, negative error code otherwise. */ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, -bool overwrite, unsigned int auxtrace_pages, +unsigned int auxtrace_pages, bool auxtrace_overwrite) { struct perf_evsel *evsel; const struct cpu_map *cpus = evlist->cpus; const struct thread_map *threads = evlist->threads; struct mmap_params mp = { - .prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), + .prot = PROT_READ | PROT_WRITE, }; if (!evlist->mmap) @@ -1070,7 +1070,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) return -ENOMEM; - evlist->overwrite = overwrite; + evlist->overwrite = false; evlist->mmap_len = perf_evlist__mmap_size(pages); pr_debug("mmap size %zuB\n", evlist->mmap_len); mp.mask = evlist->mmap_len - page_size - 1; @@ -1093,7 +1093,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages) { - return perf_evlist__mmap_ex(evlist, pages, false, 0, false); + return perf_evlist__mmap_ex(evlist, pages, 0, false); } int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index f0f2c8b..424a3d6 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -169,7 +169,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, unsigned long perf_event_mlock_kb_in_pages(void); int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, -bool overwrite, unsigned int auxtrace_pages, +unsigned int auxtrace_pages, bool auxtrace_overwrite); int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages); void perf_evlist__munmap(struct perf_evlist *evlist);
[tip:perf/core] perf evlist: Remove 'overwrite' parameter from perf_evlist__mmap
Commit-ID: f74b9d3a1ac2b9c3ae1475f474ca0e6644746fbf Gitweb: https://git.kernel.org/tip/f74b9d3a1ac2b9c3ae1475f474ca0e6644746fbf Author: Wang Nan <wangn...@huawei.com> AuthorDate: Sun, 3 Dec 2017 02:00:37 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Tue, 5 Dec 2017 15:43:53 -0300 perf evlist: Remove 'overwrite' parameter from perf_evlist__mmap Now all perf_evlist__mmap's users doesn't set 'overwrite'. Remove it from arguments list. Signed-off-by: Wang Nan <wangn...@huawei.com> Acked-by: Namhyung Kim <namhy...@kernel.org> Cc: Jiri Olsa <jo...@redhat.com> Cc: Kan Liang <kan.li...@intel.com> Link: http://lkml.kernel.org/r/20171203020044.81680-2-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c| 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 5 ++--- tools/perf/util/evlist.h | 3 +-- tools/perf/util/python.c | 2 +- 17 files changed, 18 insertions(+), 20 deletions(-) diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index b59678e..06abe81 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -84,7 +84,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe CHECK__(perf_evlist__open(evlist)); - CHECK__(perf_evlist__mmap(evlist, UINT_MAX, false)); + CHECK__(perf_evlist__mmap(evlist, UINT_MAX)); pc = evlist->mmap[0].base; ret = perf_read_tsc_conversion(pc, ); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 597c7de..9885316 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1044,7 +1044,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) goto out; } - if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) { + if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) { ui__error("Failed to mmap the events: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); perf_evlist__close(evlist); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0077724..540461f 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -907,7 +907,7 @@ try_again: } } - if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) { + if (perf_evlist__mmap(evlist, opts->mmap_pages) < 0) { ui__error("Failed to mmap with %d (%s)\n", errno, str_error_r(errno, msg, sizeof(msg))); goto out_err; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 84debdb..7c57898 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2437,7 +2437,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_error_apply_filters; - err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false); + err = perf_evlist__mmap(evlist, trace->opts.mmap_pages); if (err < 0) goto out_error_mmap; diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 43a8c6a..cf37e43 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -59,7 +59,7 @@ static int do_test(struct perf_evlist *evlist, int mmap_pages, int err; char sbuf[STRERR_BUFSIZE]; - err = perf_evlist__mmap(evlist, mmap_pages, false); + err = perf_evlist__mmap(evlist, mmap_pages); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 34c22cd..c433dd3 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -167,7 +167,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), goto out_delete_evlist; } - err = perf_evlist__m
[tip:perf/core] perf evlist: Remove 'overwrite' parameter from perf_evlist__mmap
Commit-ID: f74b9d3a1ac2b9c3ae1475f474ca0e6644746fbf Gitweb: https://git.kernel.org/tip/f74b9d3a1ac2b9c3ae1475f474ca0e6644746fbf Author: Wang Nan AuthorDate: Sun, 3 Dec 2017 02:00:37 + Committer: Arnaldo Carvalho de Melo CommitDate: Tue, 5 Dec 2017 15:43:53 -0300 perf evlist: Remove 'overwrite' parameter from perf_evlist__mmap Now all perf_evlist__mmap's users doesn't set 'overwrite'. Remove it from arguments list. Signed-off-by: Wang Nan Acked-by: Namhyung Kim Cc: Jiri Olsa Cc: Kan Liang Link: http://lkml.kernel.org/r/20171203020044.81680-2-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c| 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 5 ++--- tools/perf/util/evlist.h | 3 +-- tools/perf/util/python.c | 2 +- 17 files changed, 18 insertions(+), 20 deletions(-) diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index b59678e..06abe81 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -84,7 +84,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe CHECK__(perf_evlist__open(evlist)); - CHECK__(perf_evlist__mmap(evlist, UINT_MAX, false)); + CHECK__(perf_evlist__mmap(evlist, UINT_MAX)); pc = evlist->mmap[0].base; ret = perf_read_tsc_conversion(pc, ); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 597c7de..9885316 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1044,7 +1044,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) goto out; } - if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) { + if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) { ui__error("Failed to mmap the events: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); perf_evlist__close(evlist); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0077724..540461f 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -907,7 +907,7 @@ try_again: } } - if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) { + if (perf_evlist__mmap(evlist, opts->mmap_pages) < 0) { ui__error("Failed to mmap with %d (%s)\n", errno, str_error_r(errno, msg, sizeof(msg))); goto out_err; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 84debdb..7c57898 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2437,7 +2437,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_error_apply_filters; - err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false); + err = perf_evlist__mmap(evlist, trace->opts.mmap_pages); if (err < 0) goto out_error_mmap; diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 43a8c6a..cf37e43 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -59,7 +59,7 @@ static int do_test(struct perf_evlist *evlist, int mmap_pages, int err; char sbuf[STRERR_BUFSIZE]; - err = perf_evlist__mmap(evlist, mmap_pages, false); + err = perf_evlist__mmap(evlist, mmap_pages); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 34c22cd..c433dd3 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -167,7 +167,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), goto out_delete_evlist; } - err = perf_evlist__mmap(evlist, opts.mmap_pages, false); + err = perf_evlist__mmap(evlist, opts.mmap_pages); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n",
[PATCH] perf tools: Fix compiling error in libunwind x86
Fix a compiling error: ... CC util/libunwind/x86_32.o In file included from util/libunwind/x86_32.c:33:0: util/libunwind/../../arch/x86/util/unwind-libunwind.c: In function 'libunwind__x86_reg_id': util/libunwind/../../arch/x86/util/unwind-libunwind.c:110:11: error: 'EINVAL' undeclared (first use in this function) return -EINVAL; ^ util/libunwind/../../arch/x86/util/unwind-libunwind.c:110:11: note: each undeclared identifier is reported only once for each function it appears in mv: cannot stat 'util/libunwind/.x86_32.o.tmp': No such file or directory make[4]: *** [util/libunwind/x86_32.o] Error 1 make[3]: *** [util] Error 2 make[2]: *** [libperf-in.o] Error 2 make[1]: *** [sub-make] Error 2 make: *** [all] Error 2 It happens when libunwind-x86 feature is detected. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/arch/x86/util/unwind-libunwind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/arch/x86/util/unwind-libunwind.c b/tools/perf/arch/x86/util/unwind-libunwind.c index 9c917f8..05920e3 100644 --- a/tools/perf/arch/x86/util/unwind-libunwind.c +++ b/tools/perf/arch/x86/util/unwind-libunwind.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 -#ifndef REMOTE_UNWIND_LIBUNWIND #include +#ifndef REMOTE_UNWIND_LIBUNWIND #include #include "perf_regs.h" #include "../../util/unwind.h" -- 2.10.1
[PATCH] perf tools: Fix compiling error in libunwind x86
Fix a compiling error: ... CC util/libunwind/x86_32.o In file included from util/libunwind/x86_32.c:33:0: util/libunwind/../../arch/x86/util/unwind-libunwind.c: In function 'libunwind__x86_reg_id': util/libunwind/../../arch/x86/util/unwind-libunwind.c:110:11: error: 'EINVAL' undeclared (first use in this function) return -EINVAL; ^ util/libunwind/../../arch/x86/util/unwind-libunwind.c:110:11: note: each undeclared identifier is reported only once for each function it appears in mv: cannot stat 'util/libunwind/.x86_32.o.tmp': No such file or directory make[4]: *** [util/libunwind/x86_32.o] Error 1 make[3]: *** [util] Error 2 make[2]: *** [libperf-in.o] Error 2 make[1]: *** [sub-make] Error 2 make: *** [all] Error 2 It happens when libunwind-x86 feature is detected. Signed-off-by: Wang Nan --- tools/perf/arch/x86/util/unwind-libunwind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/arch/x86/util/unwind-libunwind.c b/tools/perf/arch/x86/util/unwind-libunwind.c index 9c917f8..05920e3 100644 --- a/tools/perf/arch/x86/util/unwind-libunwind.c +++ b/tools/perf/arch/x86/util/unwind-libunwind.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 -#ifndef REMOTE_UNWIND_LIBUNWIND #include +#ifndef REMOTE_UNWIND_LIBUNWIND #include #include "perf_regs.h" #include "../../util/unwind.h" -- 2.10.1
[PATCH v3 2/3] perf tools: Don't discard prev in backward mode
Perf record can switch output. The new output should only store the data after switching. However, in overwrite backward mode, the new output still have the data from old output. That also brings extra overhead. At the end of mmap_read, the position of processed ring buffer is saved in md->prev. Next mmap_read should be end in md->prev if it is not overwriten. That avoids to process duplicate data. However, the md->prev is discarded. So next mmap_read has to process whole valid ring buffer, which probably include the old processed data. Avoid calling backward_rb_find_range() when md->prev is still available. Signed-off-by: Wang Nan <wangn...@huawei.com> Tested-by: Kan Liang <kan.li...@intel.com> --- tools/perf/util/mmap.c | 33 +++-- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 3f262e7..5f8cb15 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -267,18 +267,6 @@ static int backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 return -1; } -static int rb_find_range(void *data, int mask, u64 head, u64 old, -u64 *start, u64 *end, bool backward) -{ - if (!backward) { - *start = old; - *end = head; - return 0; - } - - return backward_rb_find_range(data, mask, head, start, end); -} - int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)) { @@ -290,19 +278,28 @@ int perf_mmap__push(struct perf_mmap *md, bool backward, void *buf; int rc = 0; - if (rb_find_range(data, md->mask, head, old, , , backward)) - return -1; + start = backward ? head : old; + end = backward ? old : head; if (start == end) return 0; size = end - start; if (size > (unsigned long)(md->mask) + 1) { - WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); + if (!backward) { + WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); - md->prev = head; - perf_mmap__consume(md, backward); - return 0; + md->prev = head; + perf_mmap__consume(md, backward); + return 0; + } + + /* +* Backward ring buffer is full. We still have a chance to read +* most of data from it. +*/ + if (backward_rb_find_range(data, md->mask, head, , )) + return -1; } if ((start & md->mask) + size != (end & md->mask)) { -- 2.10.1
[PATCH v3 3/3] perf tools: Replace 'backward' to 'overwrite' in evlist. mmap and record
Remove the backward/forward concept to make it uniform with user interface (the '--overwrite' option). Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/builtin-record.c | 14 +++--- tools/perf/tests/backward-ring-buffer.c | 4 ++-- tools/perf/util/evlist.c| 30 +++--- tools/perf/util/evlist.h| 2 +- tools/perf/util/mmap.c | 22 +++--- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 26b8571..0a5749e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -479,7 +479,7 @@ static struct perf_event_header finished_round_event = { }; static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist, - bool backward) + bool overwrite) { u64 bytes_written = rec->bytes_written; int i; @@ -489,18 +489,18 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli if (!evlist) return 0; - maps = backward ? evlist->backward_mmap : evlist->mmap; + maps = overwrite ? evlist->overwrite_mmap : evlist->mmap; if (!maps) return 0; - if (backward && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) + if (overwrite && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) return 0; for (i = 0; i < evlist->nr_mmaps; i++) { struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], overwrite, rec, record__pushfn) != 0) { rc = -1; goto out; } @@ -520,7 +520,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli if (bytes_written != rec->bytes_written) rc = record__write(rec, _round_event, sizeof(finished_round_event)); - if (backward) + if (overwrite) perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY); out: return rc; @@ -692,8 +692,8 @@ perf_evlist__pick_pc(struct perf_evlist *evlist) if (evlist) { if (evlist->mmap && evlist->mmap[0].base) return evlist->mmap[0].base; - if (evlist->backward_mmap && evlist->backward_mmap[0].base) - return evlist->backward_mmap[0].base; + if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].base) + return evlist->overwrite_mmap[0].base; } return NULL; } diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index cf37e43..4035d43 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -33,8 +33,8 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; - perf_mmap__read_catchup(>backward_mmap[i]); - while ((event = perf_mmap__read_backward(>backward_mmap[i])) != NULL) { + perf_mmap__read_catchup(>overwrite_mmap[i]); + while ((event = perf_mmap__read_backward(>overwrite_mmap[i])) != NULL) { const u32 type = event->header.type; switch (type) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index b1cea71..3570355 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -125,7 +125,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist) void perf_evlist__exit(struct perf_evlist *evlist) { zfree(>mmap); - zfree(>backward_mmap); + zfree(>overwrite_mmap); fdarray__exit(>pollfd); } @@ -675,11 +675,11 @@ static int perf_evlist__set_paused(struct perf_evlist *evlist, bool value) { int i; - if (!evlist->backward_mmap) + if (!evlist->overwrite_mmap) return 0; for (i = 0; i < evlist->nr_mmaps; i++) { - int fd = evlist->backward_mmap[i].fd; + int fd = evlist->overwrite_mmap[i].fd; int err; if (fd < 0) @@ -749,16 +749,16 @@ static void perf_evlist__munmap_nofree(struct perf_evlist *evlist) for (i = 0; i < evlist->nr_mmaps; i++) perf_mmap__munmap(>mmap[i]); - if (evlist->backward_mmap) + if (evlist->overwrite_mmap) for (i = 0; i < evlist->
[PATCH v3 2/3] perf tools: Don't discard prev in backward mode
Perf record can switch output. The new output should only store the data after switching. However, in overwrite backward mode, the new output still have the data from old output. That also brings extra overhead. At the end of mmap_read, the position of processed ring buffer is saved in md->prev. Next mmap_read should be end in md->prev if it is not overwriten. That avoids to process duplicate data. However, the md->prev is discarded. So next mmap_read has to process whole valid ring buffer, which probably include the old processed data. Avoid calling backward_rb_find_range() when md->prev is still available. Signed-off-by: Wang Nan Tested-by: Kan Liang --- tools/perf/util/mmap.c | 33 +++-- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 3f262e7..5f8cb15 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -267,18 +267,6 @@ static int backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 return -1; } -static int rb_find_range(void *data, int mask, u64 head, u64 old, -u64 *start, u64 *end, bool backward) -{ - if (!backward) { - *start = old; - *end = head; - return 0; - } - - return backward_rb_find_range(data, mask, head, start, end); -} - int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)) { @@ -290,19 +278,28 @@ int perf_mmap__push(struct perf_mmap *md, bool backward, void *buf; int rc = 0; - if (rb_find_range(data, md->mask, head, old, , , backward)) - return -1; + start = backward ? head : old; + end = backward ? old : head; if (start == end) return 0; size = end - start; if (size > (unsigned long)(md->mask) + 1) { - WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); + if (!backward) { + WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); - md->prev = head; - perf_mmap__consume(md, backward); - return 0; + md->prev = head; + perf_mmap__consume(md, backward); + return 0; + } + + /* +* Backward ring buffer is full. We still have a chance to read +* most of data from it. +*/ + if (backward_rb_find_range(data, md->mask, head, , )) + return -1; } if ((start & md->mask) + size != (end & md->mask)) { -- 2.10.1
[PATCH v3 3/3] perf tools: Replace 'backward' to 'overwrite' in evlist. mmap and record
Remove the backward/forward concept to make it uniform with user interface (the '--overwrite' option). Signed-off-by: Wang Nan --- tools/perf/builtin-record.c | 14 +++--- tools/perf/tests/backward-ring-buffer.c | 4 ++-- tools/perf/util/evlist.c| 30 +++--- tools/perf/util/evlist.h| 2 +- tools/perf/util/mmap.c | 22 +++--- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 26b8571..0a5749e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -479,7 +479,7 @@ static struct perf_event_header finished_round_event = { }; static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist, - bool backward) + bool overwrite) { u64 bytes_written = rec->bytes_written; int i; @@ -489,18 +489,18 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli if (!evlist) return 0; - maps = backward ? evlist->backward_mmap : evlist->mmap; + maps = overwrite ? evlist->overwrite_mmap : evlist->mmap; if (!maps) return 0; - if (backward && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) + if (overwrite && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) return 0; for (i = 0; i < evlist->nr_mmaps; i++) { struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], overwrite, rec, record__pushfn) != 0) { rc = -1; goto out; } @@ -520,7 +520,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli if (bytes_written != rec->bytes_written) rc = record__write(rec, _round_event, sizeof(finished_round_event)); - if (backward) + if (overwrite) perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY); out: return rc; @@ -692,8 +692,8 @@ perf_evlist__pick_pc(struct perf_evlist *evlist) if (evlist) { if (evlist->mmap && evlist->mmap[0].base) return evlist->mmap[0].base; - if (evlist->backward_mmap && evlist->backward_mmap[0].base) - return evlist->backward_mmap[0].base; + if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].base) + return evlist->overwrite_mmap[0].base; } return NULL; } diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index cf37e43..4035d43 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -33,8 +33,8 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; - perf_mmap__read_catchup(>backward_mmap[i]); - while ((event = perf_mmap__read_backward(>backward_mmap[i])) != NULL) { + perf_mmap__read_catchup(>overwrite_mmap[i]); + while ((event = perf_mmap__read_backward(>overwrite_mmap[i])) != NULL) { const u32 type = event->header.type; switch (type) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index b1cea71..3570355 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -125,7 +125,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist) void perf_evlist__exit(struct perf_evlist *evlist) { zfree(>mmap); - zfree(>backward_mmap); + zfree(>overwrite_mmap); fdarray__exit(>pollfd); } @@ -675,11 +675,11 @@ static int perf_evlist__set_paused(struct perf_evlist *evlist, bool value) { int i; - if (!evlist->backward_mmap) + if (!evlist->overwrite_mmap) return 0; for (i = 0; i < evlist->nr_mmaps; i++) { - int fd = evlist->backward_mmap[i].fd; + int fd = evlist->overwrite_mmap[i].fd; int err; if (fd < 0) @@ -749,16 +749,16 @@ static void perf_evlist__munmap_nofree(struct perf_evlist *evlist) for (i = 0; i < evlist->nr_mmaps; i++) perf_mmap__munmap(>mmap[i]); - if (evlist->backward_mmap) + if (evlist->overwrite_mmap) for (i = 0; i < evlist->nr_mmaps; i++) -
[PATCH v3 1/3] perf mmap: Fix perf backward recording
perf record backward recording doesn't work as we expected: it never overwrite when ring buffer full. Test: (Run a busy python printing task background like this: while True: print 123 send SIGUSR2 to perf to capture snapshot.) # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101520743 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521251 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521692 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101521936 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101520743 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521251 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521692 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 Timestamps are never change, but my background task is a dead loop, can easily overwhelme the ring buffer. This patch fix it by force unsetting PROT_WRITE for backward ring buffer, so all backward ring buffer become overwrite ring buffer. Test result: # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101285323 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290053 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290446 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101290837 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101285323 | head -n3 python 2545 [000] 11064.268083: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11064.268084: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11064.268086: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101290 | head -n3 failed to open ./perf.data.2017110101290: No such file or directory # ./perf script -i ./perf.data.2017110101290053 | head -n3 python 2545 [000] 11071.564062: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11071.564064: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11071.564066: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) # ./perf script -i ./perf.data.2017110101290 | head -n3 perf.data.2017110101290053 perf.data.2017110101290446 perf.data.2017110101290837 # ./perf script -i ./perf.data.2017110101290446 | head -n3 sshd 1321 [000] 11075.499473: raw_syscalls:sys_exit: NR 14 = 0 sshd 1321 [000] 11075.499474: raw_syscalls:sys_enter: NR 14 (2, 7ffe98899490, 0, 8, 0, 3000) sshd 1321 [000] 11075.499474: raw_syscalls:sys_exit: NR 14 = 0 # ./perf script -i ./perf.data.2017110101290837 | head -n3 python 2545 [000] 11079.280844: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11079.280847: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11079.280850: raw_syscalls:sys_exit: NR 1 = 4 Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/util/evlist.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 68c1f95..b1cea71 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -812,6 +812,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, int fd; int cpu; + mp->prot = PROT_READ | PROT_WRITE; if (evsel->attr.write_backward) { output = _output_backward; maps = evlist->backward_mmap; @@ -824,6 +
[PATCH v3 1/3] perf mmap: Fix perf backward recording
perf record backward recording doesn't work as we expected: it never overwrite when ring buffer full. Test: (Run a busy python printing task background like this: while True: print 123 send SIGUSR2 to perf to capture snapshot.) # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101520743 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521251 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521692 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101521936 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101520743 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521251 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521692 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 Timestamps are never change, but my background task is a dead loop, can easily overwhelme the ring buffer. This patch fix it by force unsetting PROT_WRITE for backward ring buffer, so all backward ring buffer become overwrite ring buffer. Test result: # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101285323 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290053 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290446 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101290837 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101285323 | head -n3 python 2545 [000] 11064.268083: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11064.268084: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11064.268086: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101290 | head -n3 failed to open ./perf.data.2017110101290: No such file or directory # ./perf script -i ./perf.data.2017110101290053 | head -n3 python 2545 [000] 11071.564062: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11071.564064: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11071.564066: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) # ./perf script -i ./perf.data.2017110101290 | head -n3 perf.data.2017110101290053 perf.data.2017110101290446 perf.data.2017110101290837 # ./perf script -i ./perf.data.2017110101290446 | head -n3 sshd 1321 [000] 11075.499473: raw_syscalls:sys_exit: NR 14 = 0 sshd 1321 [000] 11075.499474: raw_syscalls:sys_enter: NR 14 (2, 7ffe98899490, 0, 8, 0, 3000) sshd 1321 [000] 11075.499474: raw_syscalls:sys_exit: NR 14 = 0 # ./perf script -i ./perf.data.2017110101290837 | head -n3 python 2545 [000] 11079.280844: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11079.280847: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11079.280850: raw_syscalls:sys_exit: NR 1 = 4 Signed-off-by: Wang Nan --- tools/perf/util/evlist.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 68c1f95..b1cea71 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -812,6 +812,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, int fd; int cpu; + mp->prot = PROT_READ | PROT_WRITE; if (evsel->attr.write_backward) { output = _output_backward; maps = evlist->backward_mmap; @@ -824,6 +825,7 @@ s
[PATCH v3 0/3] perf tools: perf tools: Clarify overwrite and backward, bugfix
Simplify patch 1/3 following Namhyung's suggestion. Context adjustment for patch 2 and 3. Wang Nan (3): perf mmap: Fix perf backward recording perf tools: Don't discard prev in backward mode perf tools: Replace 'backward' to 'overwrite' in evlist. mmap and record tools/perf/builtin-record.c | 14 +- tools/perf/tests/backward-ring-buffer.c | 4 +-- tools/perf/util/evlist.c| 41 +- tools/perf/util/evlist.h| 2 +- tools/perf/util/mmap.c | 45 +++-- 5 files changed, 54 insertions(+), 52 deletions(-) -- 2.10.1
[PATCH v3 0/3] perf tools: perf tools: Clarify overwrite and backward, bugfix
Simplify patch 1/3 following Namhyung's suggestion. Context adjustment for patch 2 and 3. Wang Nan (3): perf mmap: Fix perf backward recording perf tools: Don't discard prev in backward mode perf tools: Replace 'backward' to 'overwrite' in evlist. mmap and record tools/perf/builtin-record.c | 14 +- tools/perf/tests/backward-ring-buffer.c | 4 +-- tools/perf/util/evlist.c| 41 +- tools/perf/util/evlist.h| 2 +- tools/perf/util/mmap.c | 45 +++-- 5 files changed, 54 insertions(+), 52 deletions(-) -- 2.10.1
[PATCH v2 0/8] perf tools: perf tools: Clarify overwrite and backward, bugfix
THe final result of this patchset is removing the concept of 'forward/backward', merge them into the concept of 'overwrite'. Patch 1 to 5 clear arguments lists of many functions, remove the 'overwrite'. Because all callers of these functions doesn't need the overwrite be set, we can simply remove them from arguments lists and adjust code as if a 'false' is given. Patch 6 fix a bug that forget to setting readonly for overwrite ring buffers. Patch 7 is suggested by Liang Kan, prevent dumpping duplicated data if there's no so many events between two dumpping commands. Patch 8 is 's/backward/overwrite'. After patch 8, the concept of 'backward' is removed from most of the code, make it uniform with user interface ('--overwrite'). Cc: Kan Liang <kan.li...@intel.com> Cc: Arnaldo Carvalho de Melo <a...@redhat.com> Cc: Jiri Olsa <jo...@kernel.org> Cc: Namhyung Kim <namhy...@kernel.org> Cc: Zhang Mengting <zhangmengt...@huawei.com> Wang Nan (8): perf tools: Remove 'overwrite' parameter from perf_evlist__mmap perf tools: Remove 'overwrite' parameter from perf_evlist__mmap_ex perf tools: Remove evlist->overwrite perf tools: Remove overwrite from arguments list of perf_mmap__push perf tools: Remove overwrite and check_messup from mmap read perf mmap: Fix perf backward recording perf tool: Don't discard prev in backward mode perf tools: Replace 'backward' to 'overwrite' in evlist, mmap and record tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 16 +++--- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 6 +-- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c| 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 53 ++-- tools/perf/util/evlist.h | 8 ++- tools/perf/util/mmap.c | 73 ++-- tools/perf/util/mmap.h | 4 +- tools/perf/util/python.c | 2 +- 20 files changed, 81 insertions(+), 107 deletions(-) -- 2.10.1
[PATCH v2 0/8] perf tools: perf tools: Clarify overwrite and backward, bugfix
THe final result of this patchset is removing the concept of 'forward/backward', merge them into the concept of 'overwrite'. Patch 1 to 5 clear arguments lists of many functions, remove the 'overwrite'. Because all callers of these functions doesn't need the overwrite be set, we can simply remove them from arguments lists and adjust code as if a 'false' is given. Patch 6 fix a bug that forget to setting readonly for overwrite ring buffers. Patch 7 is suggested by Liang Kan, prevent dumpping duplicated data if there's no so many events between two dumpping commands. Patch 8 is 's/backward/overwrite'. After patch 8, the concept of 'backward' is removed from most of the code, make it uniform with user interface ('--overwrite'). Cc: Kan Liang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Namhyung Kim Cc: Zhang Mengting Wang Nan (8): perf tools: Remove 'overwrite' parameter from perf_evlist__mmap perf tools: Remove 'overwrite' parameter from perf_evlist__mmap_ex perf tools: Remove evlist->overwrite perf tools: Remove overwrite from arguments list of perf_mmap__push perf tools: Remove overwrite and check_messup from mmap read perf mmap: Fix perf backward recording perf tool: Don't discard prev in backward mode perf tools: Replace 'backward' to 'overwrite' in evlist, mmap and record tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 16 +++--- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 6 +-- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c| 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 53 ++-- tools/perf/util/evlist.h | 8 ++- tools/perf/util/mmap.c | 73 ++-- tools/perf/util/mmap.h | 4 +- tools/perf/util/python.c | 2 +- 20 files changed, 81 insertions(+), 107 deletions(-) -- 2.10.1
[PATCH v2 6/8] perf mmap: Fix perf backward recording
perf record backward recording doesn't work as we expected: it never overwrite when ring buffer full. Test: (Run a busy printing task background like this: while True: print 123 send SIGUSR2 to perf to capture snapshot.) # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101520743 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521251 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521692 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101521936 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101520743 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521251 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521692 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 Timestamps are never change, but my background task is a dead loop, can easily overwhelme the ring buffer. This patch fix it by force unsetting PROT_WRITE for backward ring buffer, so all backward ring buffer become overwrite ring buffer. Test result: # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101285323 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290053 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290446 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101290837 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101285323 | head -n3 python 2545 [000] 11064.268083: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11064.268084: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11064.268086: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101290 | head -n3 failed to open ./perf.data.2017110101290: No such file or directory # ./perf script -i ./perf.data.2017110101290053 | head -n3 python 2545 [000] 11071.564062: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11071.564064: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11071.564066: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) # ./perf script -i ./perf.data.2017110101290 | head -n3 perf.data.2017110101290053 perf.data.2017110101290446 perf.data.2017110101290837 # ./perf script -i ./perf.data.2017110101290446 | head -n3 sshd 1321 [000] 11075.499473: raw_syscalls:sys_exit: NR 14 = 0 sshd 1321 [000] 11075.499474: raw_syscalls:sys_enter: NR 14 (2, 7ffe98899490, 0, 8, 0, 3000) sshd 1321 [000] 11075.499474: raw_syscalls:sys_exit: NR 14 = 0 # ./perf script -i ./perf.data.2017110101290837 | head -n3 python 2545 [000] 11079.280844: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11079.280847: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11079.280850: raw_syscalls:sys_exit: NR 1 = 4 Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/util/evlist.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 68c1f95..bb70aef 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -799,7 +799,7 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, } static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, - struct mmap_params *mp, int cpu_idx, + struct mmap_params mp, int cpu_idx, int thread, int *_outpu
[PATCH v2 7/8] perf tools: Don't discard prev in backward mode
Perf record can switch output. The new output should only store the data after switching. However, in overwrite backward mode, the new output still have the data from old output. That also brings extra overhead. At the end of mmap_read, the position of processed ring buffer is saved in md->prev. Next mmap_read should be end in md->prev if it is not overwriten. That avoids to process duplicate data. However, the md->prev is discarded. So next mmap_read has to process whole valid ring buffer, which probably include the old processed data. Avoid calling backward_rb_find_range() when md->prev is still available. Signed-off-by: Wang Nan <wangn...@huawei.com> Tested-by: Kan Liang <kan.li...@intel.com> --- tools/perf/util/mmap.c | 33 +++-- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 3f262e7..5f8cb15 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -267,18 +267,6 @@ static int backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 return -1; } -static int rb_find_range(void *data, int mask, u64 head, u64 old, -u64 *start, u64 *end, bool backward) -{ - if (!backward) { - *start = old; - *end = head; - return 0; - } - - return backward_rb_find_range(data, mask, head, start, end); -} - int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)) { @@ -290,19 +278,28 @@ int perf_mmap__push(struct perf_mmap *md, bool backward, void *buf; int rc = 0; - if (rb_find_range(data, md->mask, head, old, , , backward)) - return -1; + start = backward ? head : old; + end = backward ? old : head; if (start == end) return 0; size = end - start; if (size > (unsigned long)(md->mask) + 1) { - WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); + if (!backward) { + WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); - md->prev = head; - perf_mmap__consume(md, backward); - return 0; + md->prev = head; + perf_mmap__consume(md, backward); + return 0; + } + + /* +* Backward ring buffer is full. We still have a chance to read +* most of data from it. +*/ + if (backward_rb_find_range(data, md->mask, head, , )) + return -1; } if ((start & md->mask) + size != (end & md->mask)) { -- 2.10.1
[PATCH v2 6/8] perf mmap: Fix perf backward recording
perf record backward recording doesn't work as we expected: it never overwrite when ring buffer full. Test: (Run a busy printing task background like this: while True: print 123 send SIGUSR2 to perf to capture snapshot.) # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101520743 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521251 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521692 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101521936 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101520743 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521251 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521692 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 Timestamps are never change, but my background task is a dead loop, can easily overwhelme the ring buffer. This patch fix it by force unsetting PROT_WRITE for backward ring buffer, so all backward ring buffer become overwrite ring buffer. Test result: # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101285323 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290053 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290446 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101290837 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101285323 | head -n3 python 2545 [000] 11064.268083: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11064.268084: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11064.268086: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101290 | head -n3 failed to open ./perf.data.2017110101290: No such file or directory # ./perf script -i ./perf.data.2017110101290053 | head -n3 python 2545 [000] 11071.564062: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11071.564064: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11071.564066: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) # ./perf script -i ./perf.data.2017110101290 | head -n3 perf.data.2017110101290053 perf.data.2017110101290446 perf.data.2017110101290837 # ./perf script -i ./perf.data.2017110101290446 | head -n3 sshd 1321 [000] 11075.499473: raw_syscalls:sys_exit: NR 14 = 0 sshd 1321 [000] 11075.499474: raw_syscalls:sys_enter: NR 14 (2, 7ffe98899490, 0, 8, 0, 3000) sshd 1321 [000] 11075.499474: raw_syscalls:sys_exit: NR 14 = 0 # ./perf script -i ./perf.data.2017110101290837 | head -n3 python 2545 [000] 11079.280844: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11079.280847: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11079.280850: raw_syscalls:sys_exit: NR 1 = 4 Signed-off-by: Wang Nan --- tools/perf/util/evlist.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 68c1f95..bb70aef 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -799,7 +799,7 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, } static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, - struct mmap_params *mp, int cpu_idx, + struct mmap_params mp, int cpu_idx, int thread, int *_output, int *_output_backward
[PATCH v2 7/8] perf tools: Don't discard prev in backward mode
Perf record can switch output. The new output should only store the data after switching. However, in overwrite backward mode, the new output still have the data from old output. That also brings extra overhead. At the end of mmap_read, the position of processed ring buffer is saved in md->prev. Next mmap_read should be end in md->prev if it is not overwriten. That avoids to process duplicate data. However, the md->prev is discarded. So next mmap_read has to process whole valid ring buffer, which probably include the old processed data. Avoid calling backward_rb_find_range() when md->prev is still available. Signed-off-by: Wang Nan Tested-by: Kan Liang --- tools/perf/util/mmap.c | 33 +++-- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 3f262e7..5f8cb15 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -267,18 +267,6 @@ static int backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 return -1; } -static int rb_find_range(void *data, int mask, u64 head, u64 old, -u64 *start, u64 *end, bool backward) -{ - if (!backward) { - *start = old; - *end = head; - return 0; - } - - return backward_rb_find_range(data, mask, head, start, end); -} - int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)) { @@ -290,19 +278,28 @@ int perf_mmap__push(struct perf_mmap *md, bool backward, void *buf; int rc = 0; - if (rb_find_range(data, md->mask, head, old, , , backward)) - return -1; + start = backward ? head : old; + end = backward ? old : head; if (start == end) return 0; size = end - start; if (size > (unsigned long)(md->mask) + 1) { - WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); + if (!backward) { + WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); - md->prev = head; - perf_mmap__consume(md, backward); - return 0; + md->prev = head; + perf_mmap__consume(md, backward); + return 0; + } + + /* +* Backward ring buffer is full. We still have a chance to read +* most of data from it. +*/ + if (backward_rb_find_range(data, md->mask, head, , )) + return -1; } if ((start & md->mask) + size != (end & md->mask)) { -- 2.10.1
[PATCH v2 5/8] perf tools: Remove overwrite and check_messup from mmap read
All perf_mmap__read_forward() read from read-write ring buffer, so no need check_messup. Reading from backward ring buffer doesn't require check_messup because it never mess up. Cleanup arguments lists. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/util/evlist.c | 2 +- tools/perf/util/mmap.c | 28 tools/perf/util/mmap.h | 2 +- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index a59134f..68c1f95 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -711,7 +711,7 @@ union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int * No need for read-write ring buffer: kernel stop outputting when * it hit md->prev (perf_mmap__consume()). */ - return perf_mmap__read_forward(md, false); + return perf_mmap__read_forward(md); } union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 703ed41..3f262e7 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -21,33 +21,13 @@ size_t perf_mmap__mmap_len(struct perf_mmap *map) } /* When check_messup is true, 'end' must points to a good entry */ -static union perf_event *perf_mmap__read(struct perf_mmap *map, bool check_messup, +static union perf_event *perf_mmap__read(struct perf_mmap *map, u64 start, u64 end, u64 *prev) { unsigned char *data = map->base + page_size; union perf_event *event = NULL; int diff = end - start; - if (check_messup) { - /* -* If we're further behind than half the buffer, there's a chance -* the writer will bite our tail and mess up the samples under us. -* -* If we somehow ended up ahead of the 'end', we got messed up. -* -* In either case, truncate and restart at 'end'. -*/ - if (diff > map->mask / 2 || diff < 0) { - fprintf(stderr, "WARNING: failed to keep up with mmap data.\n"); - - /* -* 'end' points to a known good entry, start there. -*/ - start = end; - diff = 0; - } - } - if (diff >= (int)sizeof(event->header)) { size_t size; @@ -89,7 +69,7 @@ static union perf_event *perf_mmap__read(struct perf_mmap *map, bool check_messu return event; } -union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup) +union perf_event *perf_mmap__read_forward(struct perf_mmap *map) { u64 head; u64 old = map->prev; @@ -102,7 +82,7 @@ union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_mess head = perf_mmap__read_head(map); - return perf_mmap__read(map, check_messup, old, head, >prev); + return perf_mmap__read(map, old, head, >prev); } union perf_event *perf_mmap__read_backward(struct perf_mmap *map) @@ -138,7 +118,7 @@ union perf_event *perf_mmap__read_backward(struct perf_mmap *map) else end = head + map->mask + 1; - return perf_mmap__read(map, false, start, end, >prev); + return perf_mmap__read(map, start, end, >prev); } void perf_mmap__read_catchup(struct perf_mmap *map) diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 2c3d291..d640273 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -86,7 +86,7 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) pc->data_tail = tail; } -union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup); +union perf_event *perf_mmap__read_forward(struct perf_mmap *map); union perf_event *perf_mmap__read_backward(struct perf_mmap *map); int perf_mmap__push(struct perf_mmap *md, bool backward, -- 2.10.1
[PATCH v2 5/8] perf tools: Remove overwrite and check_messup from mmap read
All perf_mmap__read_forward() read from read-write ring buffer, so no need check_messup. Reading from backward ring buffer doesn't require check_messup because it never mess up. Cleanup arguments lists. Signed-off-by: Wang Nan --- tools/perf/util/evlist.c | 2 +- tools/perf/util/mmap.c | 28 tools/perf/util/mmap.h | 2 +- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index a59134f..68c1f95 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -711,7 +711,7 @@ union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int * No need for read-write ring buffer: kernel stop outputting when * it hit md->prev (perf_mmap__consume()). */ - return perf_mmap__read_forward(md, false); + return perf_mmap__read_forward(md); } union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 703ed41..3f262e7 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -21,33 +21,13 @@ size_t perf_mmap__mmap_len(struct perf_mmap *map) } /* When check_messup is true, 'end' must points to a good entry */ -static union perf_event *perf_mmap__read(struct perf_mmap *map, bool check_messup, +static union perf_event *perf_mmap__read(struct perf_mmap *map, u64 start, u64 end, u64 *prev) { unsigned char *data = map->base + page_size; union perf_event *event = NULL; int diff = end - start; - if (check_messup) { - /* -* If we're further behind than half the buffer, there's a chance -* the writer will bite our tail and mess up the samples under us. -* -* If we somehow ended up ahead of the 'end', we got messed up. -* -* In either case, truncate and restart at 'end'. -*/ - if (diff > map->mask / 2 || diff < 0) { - fprintf(stderr, "WARNING: failed to keep up with mmap data.\n"); - - /* -* 'end' points to a known good entry, start there. -*/ - start = end; - diff = 0; - } - } - if (diff >= (int)sizeof(event->header)) { size_t size; @@ -89,7 +69,7 @@ static union perf_event *perf_mmap__read(struct perf_mmap *map, bool check_messu return event; } -union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup) +union perf_event *perf_mmap__read_forward(struct perf_mmap *map) { u64 head; u64 old = map->prev; @@ -102,7 +82,7 @@ union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_mess head = perf_mmap__read_head(map); - return perf_mmap__read(map, check_messup, old, head, >prev); + return perf_mmap__read(map, old, head, >prev); } union perf_event *perf_mmap__read_backward(struct perf_mmap *map) @@ -138,7 +118,7 @@ union perf_event *perf_mmap__read_backward(struct perf_mmap *map) else end = head + map->mask + 1; - return perf_mmap__read(map, false, start, end, >prev); + return perf_mmap__read(map, start, end, >prev); } void perf_mmap__read_catchup(struct perf_mmap *map) diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 2c3d291..d640273 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -86,7 +86,7 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) pc->data_tail = tail; } -union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup); +union perf_event *perf_mmap__read_forward(struct perf_mmap *map); union perf_event *perf_mmap__read_backward(struct perf_mmap *map); int perf_mmap__push(struct perf_mmap *md, bool backward, -- 2.10.1
[PATCH v2 4/8] perf tools: Remove overwrite from arguments list of perf_mmap__push
'overwrite' argument is always 'false'. Revmove it from arguments list of perf_mmap__push. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/builtin-record.c | 2 +- tools/perf/util/mmap.c | 6 +++--- tools/perf/util/mmap.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 3bc6cee..26b8571 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -500,7 +500,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], false, backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], backward, rec, record__pushfn) != 0) { rc = -1; goto out; } diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 9fe5f9c..703ed41 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -299,7 +299,7 @@ static int rb_find_range(void *data, int mask, u64 head, u64 old, return backward_rb_find_range(data, mask, head, start, end); } -int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, +int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)) { u64 head = perf_mmap__read_head(md); @@ -321,7 +321,7 @@ int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); md->prev = head; - perf_mmap__consume(md, overwrite || backward); + perf_mmap__consume(md, backward); return 0; } @@ -346,7 +346,7 @@ int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, } md->prev = head; - perf_mmap__consume(md, overwrite || backward); + perf_mmap__consume(md, backward); out: return rc; } diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index efd78b8..2c3d291 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -89,7 +89,7 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup); union perf_event *perf_mmap__read_backward(struct perf_mmap *map); -int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, +int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)); size_t perf_mmap__mmap_len(struct perf_mmap *map); -- 2.10.1
[PATCH v2 4/8] perf tools: Remove overwrite from arguments list of perf_mmap__push
'overwrite' argument is always 'false'. Revmove it from arguments list of perf_mmap__push. Signed-off-by: Wang Nan --- tools/perf/builtin-record.c | 2 +- tools/perf/util/mmap.c | 6 +++--- tools/perf/util/mmap.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 3bc6cee..26b8571 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -500,7 +500,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], false, backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], backward, rec, record__pushfn) != 0) { rc = -1; goto out; } diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 9fe5f9c..703ed41 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -299,7 +299,7 @@ static int rb_find_range(void *data, int mask, u64 head, u64 old, return backward_rb_find_range(data, mask, head, start, end); } -int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, +int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)) { u64 head = perf_mmap__read_head(md); @@ -321,7 +321,7 @@ int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); md->prev = head; - perf_mmap__consume(md, overwrite || backward); + perf_mmap__consume(md, backward); return 0; } @@ -346,7 +346,7 @@ int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, } md->prev = head; - perf_mmap__consume(md, overwrite || backward); + perf_mmap__consume(md, backward); out: return rc; } diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index efd78b8..2c3d291 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -89,7 +89,7 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup); union perf_event *perf_mmap__read_backward(struct perf_mmap *map); -int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, +int perf_mmap__push(struct perf_mmap *md, bool backward, void *to, int push(void *to, void *buf, size_t size)); size_t perf_mmap__mmap_len(struct perf_mmap *map); -- 2.10.1
[PATCH v2 2/8] perf tools: Remove 'overwrite' parameter from perf_evlist__mmap_ex
All users of perf_evlist__mmap_ex set !overwrite. Remove it from its arguments list. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/builtin-record.c | 2 +- tools/perf/util/evlist.c| 8 tools/perf/util/evlist.h| 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e304bc4..08070f8 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -301,7 +301,7 @@ static int record__mmap_evlist(struct record *rec, struct record_opts *opts = >opts; char msg[512]; - if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, + if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, opts->auxtrace_mmap_pages, opts->auxtrace_snapshot_mode) < 0) { if (errno == EPERM) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 3c1778b..93272d9 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1052,14 +1052,14 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, * Return: %0 on success, negative error code otherwise. */ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, -bool overwrite, unsigned int auxtrace_pages, +unsigned int auxtrace_pages, bool auxtrace_overwrite) { struct perf_evsel *evsel; const struct cpu_map *cpus = evlist->cpus; const struct thread_map *threads = evlist->threads; struct mmap_params mp = { - .prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), + .prot = PROT_READ | PROT_WRITE, }; if (!evlist->mmap) @@ -1070,7 +1070,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) return -ENOMEM; - evlist->overwrite = overwrite; + evlist->overwrite = false; evlist->mmap_len = perf_evlist__mmap_size(pages); pr_debug("mmap size %zuB\n", evlist->mmap_len); mp.mask = evlist->mmap_len - page_size - 1; @@ -1093,7 +1093,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages) { - return perf_evlist__mmap_ex(evlist, pages, false, 0, false); + return perf_evlist__mmap_ex(evlist, pages, 0, false); } int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index f0f2c8b..424a3d6 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -169,7 +169,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, unsigned long perf_event_mlock_kb_in_pages(void); int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, -bool overwrite, unsigned int auxtrace_pages, +unsigned int auxtrace_pages, bool auxtrace_overwrite); int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages); void perf_evlist__munmap(struct perf_evlist *evlist); -- 2.10.1
[PATCH v2 2/8] perf tools: Remove 'overwrite' parameter from perf_evlist__mmap_ex
All users of perf_evlist__mmap_ex set !overwrite. Remove it from its arguments list. Signed-off-by: Wang Nan --- tools/perf/builtin-record.c | 2 +- tools/perf/util/evlist.c| 8 tools/perf/util/evlist.h| 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e304bc4..08070f8 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -301,7 +301,7 @@ static int record__mmap_evlist(struct record *rec, struct record_opts *opts = >opts; char msg[512]; - if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, + if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, opts->auxtrace_mmap_pages, opts->auxtrace_snapshot_mode) < 0) { if (errno == EPERM) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 3c1778b..93272d9 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1052,14 +1052,14 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, * Return: %0 on success, negative error code otherwise. */ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, -bool overwrite, unsigned int auxtrace_pages, +unsigned int auxtrace_pages, bool auxtrace_overwrite) { struct perf_evsel *evsel; const struct cpu_map *cpus = evlist->cpus; const struct thread_map *threads = evlist->threads; struct mmap_params mp = { - .prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), + .prot = PROT_READ | PROT_WRITE, }; if (!evlist->mmap) @@ -1070,7 +1070,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) return -ENOMEM; - evlist->overwrite = overwrite; + evlist->overwrite = false; evlist->mmap_len = perf_evlist__mmap_size(pages); pr_debug("mmap size %zuB\n", evlist->mmap_len); mp.mask = evlist->mmap_len - page_size - 1; @@ -1093,7 +1093,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages) { - return perf_evlist__mmap_ex(evlist, pages, false, 0, false); + return perf_evlist__mmap_ex(evlist, pages, 0, false); } int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index f0f2c8b..424a3d6 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -169,7 +169,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, unsigned long perf_event_mlock_kb_in_pages(void); int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, -bool overwrite, unsigned int auxtrace_pages, +unsigned int auxtrace_pages, bool auxtrace_overwrite); int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages); void perf_evlist__munmap(struct perf_evlist *evlist); -- 2.10.1
[PATCH v2 8/8] perf tools: Replace 'backward' to 'overwrite' in evlist, mmap and record
Remove the backward/forward concept to make it uniform with user interface (the '--overwrite' option). Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/builtin-record.c | 14 +++--- tools/perf/tests/backward-ring-buffer.c | 4 ++-- tools/perf/util/evlist.c| 30 +++--- tools/perf/util/evlist.h| 2 +- tools/perf/util/mmap.c | 22 +++--- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 26b8571..0a5749e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -479,7 +479,7 @@ static struct perf_event_header finished_round_event = { }; static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist, - bool backward) + bool overwrite) { u64 bytes_written = rec->bytes_written; int i; @@ -489,18 +489,18 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli if (!evlist) return 0; - maps = backward ? evlist->backward_mmap : evlist->mmap; + maps = overwrite ? evlist->overwrite_mmap : evlist->mmap; if (!maps) return 0; - if (backward && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) + if (overwrite && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) return 0; for (i = 0; i < evlist->nr_mmaps; i++) { struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], overwrite, rec, record__pushfn) != 0) { rc = -1; goto out; } @@ -520,7 +520,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli if (bytes_written != rec->bytes_written) rc = record__write(rec, _round_event, sizeof(finished_round_event)); - if (backward) + if (overwrite) perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY); out: return rc; @@ -692,8 +692,8 @@ perf_evlist__pick_pc(struct perf_evlist *evlist) if (evlist) { if (evlist->mmap && evlist->mmap[0].base) return evlist->mmap[0].base; - if (evlist->backward_mmap && evlist->backward_mmap[0].base) - return evlist->backward_mmap[0].base; + if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].base) + return evlist->overwrite_mmap[0].base; } return NULL; } diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index cf37e43..4035d43 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -33,8 +33,8 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; - perf_mmap__read_catchup(>backward_mmap[i]); - while ((event = perf_mmap__read_backward(>backward_mmap[i])) != NULL) { + perf_mmap__read_catchup(>overwrite_mmap[i]); + while ((event = perf_mmap__read_backward(>overwrite_mmap[i])) != NULL) { const u32 type = event->header.type; switch (type) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index bb70aef..2774528a 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -125,7 +125,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist) void perf_evlist__exit(struct perf_evlist *evlist) { zfree(>mmap); - zfree(>backward_mmap); + zfree(>overwrite_mmap); fdarray__exit(>pollfd); } @@ -675,11 +675,11 @@ static int perf_evlist__set_paused(struct perf_evlist *evlist, bool value) { int i; - if (!evlist->backward_mmap) + if (!evlist->overwrite_mmap) return 0; for (i = 0; i < evlist->nr_mmaps; i++) { - int fd = evlist->backward_mmap[i].fd; + int fd = evlist->overwrite_mmap[i].fd; int err; if (fd < 0) @@ -749,16 +749,16 @@ static void perf_evlist__munmap_nofree(struct perf_evlist *evlist) for (i = 0; i < evlist->nr_mmaps; i++) perf_mmap__munmap(>mmap[i]); - if (evlist->backward_mmap) + if (evlist->overwrite_mmap) for (i = 0; i < evlist->
[PATCH v2 8/8] perf tools: Replace 'backward' to 'overwrite' in evlist, mmap and record
Remove the backward/forward concept to make it uniform with user interface (the '--overwrite' option). Signed-off-by: Wang Nan --- tools/perf/builtin-record.c | 14 +++--- tools/perf/tests/backward-ring-buffer.c | 4 ++-- tools/perf/util/evlist.c| 30 +++--- tools/perf/util/evlist.h| 2 +- tools/perf/util/mmap.c | 22 +++--- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 26b8571..0a5749e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -479,7 +479,7 @@ static struct perf_event_header finished_round_event = { }; static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist, - bool backward) + bool overwrite) { u64 bytes_written = rec->bytes_written; int i; @@ -489,18 +489,18 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli if (!evlist) return 0; - maps = backward ? evlist->backward_mmap : evlist->mmap; + maps = overwrite ? evlist->overwrite_mmap : evlist->mmap; if (!maps) return 0; - if (backward && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) + if (overwrite && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) return 0; for (i = 0; i < evlist->nr_mmaps; i++) { struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], overwrite, rec, record__pushfn) != 0) { rc = -1; goto out; } @@ -520,7 +520,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli if (bytes_written != rec->bytes_written) rc = record__write(rec, _round_event, sizeof(finished_round_event)); - if (backward) + if (overwrite) perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY); out: return rc; @@ -692,8 +692,8 @@ perf_evlist__pick_pc(struct perf_evlist *evlist) if (evlist) { if (evlist->mmap && evlist->mmap[0].base) return evlist->mmap[0].base; - if (evlist->backward_mmap && evlist->backward_mmap[0].base) - return evlist->backward_mmap[0].base; + if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].base) + return evlist->overwrite_mmap[0].base; } return NULL; } diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index cf37e43..4035d43 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -33,8 +33,8 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; - perf_mmap__read_catchup(>backward_mmap[i]); - while ((event = perf_mmap__read_backward(>backward_mmap[i])) != NULL) { + perf_mmap__read_catchup(>overwrite_mmap[i]); + while ((event = perf_mmap__read_backward(>overwrite_mmap[i])) != NULL) { const u32 type = event->header.type; switch (type) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index bb70aef..2774528a 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -125,7 +125,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist) void perf_evlist__exit(struct perf_evlist *evlist) { zfree(>mmap); - zfree(>backward_mmap); + zfree(>overwrite_mmap); fdarray__exit(>pollfd); } @@ -675,11 +675,11 @@ static int perf_evlist__set_paused(struct perf_evlist *evlist, bool value) { int i; - if (!evlist->backward_mmap) + if (!evlist->overwrite_mmap) return 0; for (i = 0; i < evlist->nr_mmaps; i++) { - int fd = evlist->backward_mmap[i].fd; + int fd = evlist->overwrite_mmap[i].fd; int err; if (fd < 0) @@ -749,16 +749,16 @@ static void perf_evlist__munmap_nofree(struct perf_evlist *evlist) for (i = 0; i < evlist->nr_mmaps; i++) perf_mmap__munmap(>mmap[i]); - if (evlist->backward_mmap) + if (evlist->overwrite_mmap) for (i = 0; i < evlist->nr_mmaps; i++) -
[PATCH v2 1/8] perf tools: Remove 'overwrite' parameter from perf_evlist__mmap
Now all perf_evlist__mmap's users doesn't set 'overwrite'. Remove it from arguments list. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c| 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 5 ++--- tools/perf/util/evlist.h | 3 +-- tools/perf/util/python.c | 2 +- 17 files changed, 18 insertions(+), 20 deletions(-) diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index b59678e..06abe81 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -84,7 +84,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe CHECK__(perf_evlist__open(evlist)); - CHECK__(perf_evlist__mmap(evlist, UINT_MAX, false)); + CHECK__(perf_evlist__mmap(evlist, UINT_MAX)); pc = evlist->mmap[0].base; ret = perf_read_tsc_conversion(pc, ); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 597c7de..9885316 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1044,7 +1044,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) goto out; } - if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) { + if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) { ui__error("Failed to mmap the events: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); perf_evlist__close(evlist); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0077724..540461f 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -907,7 +907,7 @@ static int perf_top__start_counters(struct perf_top *top) } } - if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) { + if (perf_evlist__mmap(evlist, opts->mmap_pages) < 0) { ui__error("Failed to mmap with %d (%s)\n", errno, str_error_r(errno, msg, sizeof(msg))); goto out_err; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 84debdb..7c57898 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2437,7 +2437,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_error_apply_filters; - err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false); + err = perf_evlist__mmap(evlist, trace->opts.mmap_pages); if (err < 0) goto out_error_mmap; diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 43a8c6a..cf37e43 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -59,7 +59,7 @@ static int do_test(struct perf_evlist *evlist, int mmap_pages, int err; char sbuf[STRERR_BUFSIZE]; - err = perf_evlist__mmap(evlist, mmap_pages, false); + err = perf_evlist__mmap(evlist, mmap_pages); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 34c22cd..c433dd3 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -167,7 +167,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), goto out_delete_evlist; } - err = perf_evlist__mmap(evlist, opts.mmap_pages, false); + err = perf_evlist__mmap(evlist, opts.mmap_pages); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index fcc8984..3bf7b14 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -639,7 +639,7 @@ static int do_test_code_reading(bool try_kcore) break; } - ret = perf_evlist__mmap(evlist, UINT_MAX, false); + ret = perf_evlist__mmap(evl
[PATCH v2 3/8] perf tools: Remove evlist->overwrite
evlist->overwrite is set to false in all users. It can be removed. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/builtin-record.c | 2 +- tools/perf/util/evlist.c| 5 ++--- tools/perf/util/evlist.h| 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 08070f8..3bc6cee 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -500,7 +500,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], evlist->overwrite, backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], false, backward, rec, record__pushfn) != 0) { rc = -1; goto out; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 93272d9..a59134f 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -711,7 +711,7 @@ union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int * No need for read-write ring buffer: kernel stop outputting when * it hit md->prev (perf_mmap__consume()). */ - return perf_mmap__read_forward(md, evlist->overwrite); + return perf_mmap__read_forward(md, false); } union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx) @@ -738,7 +738,7 @@ void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx) void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx) { - perf_mmap__consume(>mmap[idx], evlist->overwrite); + perf_mmap__consume(>mmap[idx], false); } static void perf_evlist__munmap_nofree(struct perf_evlist *evlist) @@ -1070,7 +1070,6 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) return -ENOMEM; - evlist->overwrite = false; evlist->mmap_len = perf_evlist__mmap_size(pages); pr_debug("mmap size %zuB\n", evlist->mmap_len); mp.mask = evlist->mmap_len - page_size - 1; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 424a3d6..eec3377 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -31,7 +31,6 @@ struct perf_evlist { int nr_entries; int nr_groups; int nr_mmaps; - bool overwrite; bool enabled; bool has_user_cpus; size_t mmap_len; -- 2.10.1
[PATCH v2 1/8] perf tools: Remove 'overwrite' parameter from perf_evlist__mmap
Now all perf_evlist__mmap's users doesn't set 'overwrite'. Remove it from arguments list. Signed-off-by: Wang Nan --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c| 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 5 ++--- tools/perf/util/evlist.h | 3 +-- tools/perf/util/python.c | 2 +- 17 files changed, 18 insertions(+), 20 deletions(-) diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index b59678e..06abe81 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -84,7 +84,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe CHECK__(perf_evlist__open(evlist)); - CHECK__(perf_evlist__mmap(evlist, UINT_MAX, false)); + CHECK__(perf_evlist__mmap(evlist, UINT_MAX)); pc = evlist->mmap[0].base; ret = perf_read_tsc_conversion(pc, ); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 597c7de..9885316 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1044,7 +1044,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) goto out; } - if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) { + if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) { ui__error("Failed to mmap the events: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); perf_evlist__close(evlist); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0077724..540461f 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -907,7 +907,7 @@ static int perf_top__start_counters(struct perf_top *top) } } - if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) { + if (perf_evlist__mmap(evlist, opts->mmap_pages) < 0) { ui__error("Failed to mmap with %d (%s)\n", errno, str_error_r(errno, msg, sizeof(msg))); goto out_err; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 84debdb..7c57898 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2437,7 +2437,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_error_apply_filters; - err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false); + err = perf_evlist__mmap(evlist, trace->opts.mmap_pages); if (err < 0) goto out_error_mmap; diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 43a8c6a..cf37e43 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -59,7 +59,7 @@ static int do_test(struct perf_evlist *evlist, int mmap_pages, int err; char sbuf[STRERR_BUFSIZE]; - err = perf_evlist__mmap(evlist, mmap_pages, false); + err = perf_evlist__mmap(evlist, mmap_pages); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 34c22cd..c433dd3 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -167,7 +167,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), goto out_delete_evlist; } - err = perf_evlist__mmap(evlist, opts.mmap_pages, false); + err = perf_evlist__mmap(evlist, opts.mmap_pages); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index fcc8984..3bf7b14 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -639,7 +639,7 @@ static int do_test_code_reading(bool try_kcore) break; } - ret = perf_evlist__mmap(evlist, UINT_MAX, false); + ret = perf_evlist__mmap(evlist, UINT_MAX); if (ret < 0
[PATCH v2 3/8] perf tools: Remove evlist->overwrite
evlist->overwrite is set to false in all users. It can be removed. Signed-off-by: Wang Nan --- tools/perf/builtin-record.c | 2 +- tools/perf/util/evlist.c| 5 ++--- tools/perf/util/evlist.h| 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 08070f8..3bc6cee 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -500,7 +500,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], evlist->overwrite, backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], false, backward, rec, record__pushfn) != 0) { rc = -1; goto out; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 93272d9..a59134f 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -711,7 +711,7 @@ union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int * No need for read-write ring buffer: kernel stop outputting when * it hit md->prev (perf_mmap__consume()). */ - return perf_mmap__read_forward(md, evlist->overwrite); + return perf_mmap__read_forward(md, false); } union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx) @@ -738,7 +738,7 @@ void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx) void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx) { - perf_mmap__consume(>mmap[idx], evlist->overwrite); + perf_mmap__consume(>mmap[idx], false); } static void perf_evlist__munmap_nofree(struct perf_evlist *evlist) @@ -1070,7 +1070,6 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) return -ENOMEM; - evlist->overwrite = false; evlist->mmap_len = perf_evlist__mmap_size(pages); pr_debug("mmap size %zuB\n", evlist->mmap_len); mp.mask = evlist->mmap_len - page_size - 1; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 424a3d6..eec3377 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -31,7 +31,6 @@ struct perf_evlist { int nr_entries; int nr_groups; int nr_mmaps; - bool overwrite; bool enabled; bool has_user_cpus; size_t mmap_len; -- 2.10.1
[tip:perf/core] perf tests: Set evlist of test__task_exit() to !overwrite
Commit-ID: a0e3dd79cdd8ad838cbcefeff530a15193f8336e Gitweb: https://git.kernel.org/tip/a0e3dd79cdd8ad838cbcefeff530a15193f8336e Author: Wang Nan <wangn...@huawei.com> AuthorDate: Mon, 13 Nov 2017 01:38:07 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Thu, 16 Nov 2017 14:49:58 -0300 perf tests: Set evlist of test__task_exit() to !overwrite Changing ringbuffer to !overwrite in this task is harmless because this test uses a very low frequency (1) and using a very simple program (true). There should have only 3 events in the whole test. Overwriting is impossible to happen. Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Jiri Olsa <jo...@redhat.com> Cc: Kan Liang <kan.li...@intel.com> Cc: Namhyung Kim <namhy...@kernel.org> Link: http://lkml.kernel.org/r/20171113013809.212417-6-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/tests/task-exit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index bc4a734..98c0984 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -97,7 +97,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused goto out_delete_evlist; } - if (perf_evlist__mmap(evlist, 128, true) < 0) { + if (perf_evlist__mmap(evlist, 128, false) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist;
[tip:perf/core] perf tests: Set evlist of test__task_exit() to !overwrite
Commit-ID: a0e3dd79cdd8ad838cbcefeff530a15193f8336e Gitweb: https://git.kernel.org/tip/a0e3dd79cdd8ad838cbcefeff530a15193f8336e Author: Wang Nan AuthorDate: Mon, 13 Nov 2017 01:38:07 + Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 16 Nov 2017 14:49:58 -0300 perf tests: Set evlist of test__task_exit() to !overwrite Changing ringbuffer to !overwrite in this task is harmless because this test uses a very low frequency (1) and using a very simple program (true). There should have only 3 events in the whole test. Overwriting is impossible to happen. Signed-off-by: Wang Nan Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Link: http://lkml.kernel.org/r/20171113013809.212417-6-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/task-exit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index bc4a734..98c0984 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -97,7 +97,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused goto out_delete_evlist; } - if (perf_evlist__mmap(evlist, 128, true) < 0) { + if (perf_evlist__mmap(evlist, 128, false) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist;
[tip:perf/core] perf tests: Set evlist of test__sw_clock_freq() to !overwrite
Commit-ID: 677b0601768881934f658bebb1713c3c843893fa Gitweb: https://git.kernel.org/tip/677b0601768881934f658bebb1713c3c843893fa Author: Wang Nan <wangn...@huawei.com> AuthorDate: Mon, 13 Nov 2017 01:38:05 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Thu, 16 Nov 2017 14:49:57 -0300 perf tests: Set evlist of test__sw_clock_freq() to !overwrite Unsetting overwrite when calling perf_evlist__mmap is harmless. This commit passes false to it, makes following commits eliminate the overwrite argument easier. Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Jiri Olsa <jo...@redhat.com> Cc: Kan Liang <kan.li...@intel.com> Cc: Namhyung Kim <namhy...@kernel.org> Link: http://lkml.kernel.org/r/20171113013809.212417-4-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/tests/sw-clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 725a196..c6937ed 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -78,7 +78,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) goto out_delete_evlist; } - err = perf_evlist__mmap(evlist, 128, true); + err = perf_evlist__mmap(evlist, 128, false); if (err < 0) { pr_debug("failed to mmap event: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf)));
[tip:perf/core] perf tests: Set evlist of test__backward_ring_buffer() to !overwrite
Commit-ID: d492326f160e44e08fcf132a63163b36dd8e8839 Gitweb: https://git.kernel.org/tip/d492326f160e44e08fcf132a63163b36dd8e8839 Author: Wang Nan <wangn...@huawei.com> AuthorDate: Mon, 13 Nov 2017 01:38:04 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Thu, 16 Nov 2017 14:49:57 -0300 perf tests: Set evlist of test__backward_ring_buffer() to !overwrite Setting overwrite in perf_evlist__mmap() is meaningless because the event in this evlist is already have 'overwrite' postfix and goes to backward ring buffer automatically. Pass 'false' to perf_evlist__mmap() to make it similar to others. Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Jiri Olsa <jo...@redhat.com> Cc: Kan Liang <kan.li...@intel.com> Cc: Namhyung Kim <namhy...@kernel.org> Link: http://lkml.kernel.org/r/20171113013809.212417-3-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/tests/backward-ring-buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 71b9a0b..43a8c6a 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -59,7 +59,7 @@ static int do_test(struct perf_evlist *evlist, int mmap_pages, int err; char sbuf[STRERR_BUFSIZE]; - err = perf_evlist__mmap(evlist, mmap_pages, true); + err = perf_evlist__mmap(evlist, mmap_pages, false); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf)));
[tip:perf/core] perf tests: Set evlist of test__sw_clock_freq() to !overwrite
Commit-ID: 677b0601768881934f658bebb1713c3c843893fa Gitweb: https://git.kernel.org/tip/677b0601768881934f658bebb1713c3c843893fa Author: Wang Nan AuthorDate: Mon, 13 Nov 2017 01:38:05 + Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 16 Nov 2017 14:49:57 -0300 perf tests: Set evlist of test__sw_clock_freq() to !overwrite Unsetting overwrite when calling perf_evlist__mmap is harmless. This commit passes false to it, makes following commits eliminate the overwrite argument easier. Signed-off-by: Wang Nan Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Link: http://lkml.kernel.org/r/20171113013809.212417-4-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/sw-clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 725a196..c6937ed 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -78,7 +78,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) goto out_delete_evlist; } - err = perf_evlist__mmap(evlist, 128, true); + err = perf_evlist__mmap(evlist, 128, false); if (err < 0) { pr_debug("failed to mmap event: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf)));
[tip:perf/core] perf tests: Set evlist of test__backward_ring_buffer() to !overwrite
Commit-ID: d492326f160e44e08fcf132a63163b36dd8e8839 Gitweb: https://git.kernel.org/tip/d492326f160e44e08fcf132a63163b36dd8e8839 Author: Wang Nan AuthorDate: Mon, 13 Nov 2017 01:38:04 + Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 16 Nov 2017 14:49:57 -0300 perf tests: Set evlist of test__backward_ring_buffer() to !overwrite Setting overwrite in perf_evlist__mmap() is meaningless because the event in this evlist is already have 'overwrite' postfix and goes to backward ring buffer automatically. Pass 'false' to perf_evlist__mmap() to make it similar to others. Signed-off-by: Wang Nan Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Link: http://lkml.kernel.org/r/20171113013809.212417-3-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/backward-ring-buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 71b9a0b..43a8c6a 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -59,7 +59,7 @@ static int do_test(struct perf_evlist *evlist, int mmap_pages, int err; char sbuf[STRERR_BUFSIZE]; - err = perf_evlist__mmap(evlist, mmap_pages, true); + err = perf_evlist__mmap(evlist, mmap_pages, false); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf)));
[tip:perf/core] perf tests: Set evlist of test__basic_mmap() to !overwrite
Commit-ID: 301d724aa19add1c0cf3ec8cad0d10151d30393f Gitweb: https://git.kernel.org/tip/301d724aa19add1c0cf3ec8cad0d10151d30393f Author: Wang Nan <wangn...@huawei.com> AuthorDate: Mon, 13 Nov 2017 01:38:06 + Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Thu, 16 Nov 2017 14:49:58 -0300 perf tests: Set evlist of test__basic_mmap() to !overwrite In this test, a large ring buffer is required so all events can feed into, so overwrite or not is meaningless. Change to !overwrite so following commits can remove this argument. Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Jiri Olsa <jo...@redhat.com> Cc: Kan Liang <kan.li...@intel.com> Cc: Namhyung Kim <namhy...@kernel.org> Link: http://lkml.kernel.org/r/20171113013809.212417-5-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/tests/mmap-basic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 5a8bf31..91f10d6 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -94,7 +94,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse expected_nr_events[i] = 1 + rand() % 127; } - if (perf_evlist__mmap(evlist, 128, true) < 0) { + if (perf_evlist__mmap(evlist, 128, false) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist;
[tip:perf/core] perf tests: Set evlist of test__basic_mmap() to !overwrite
Commit-ID: 301d724aa19add1c0cf3ec8cad0d10151d30393f Gitweb: https://git.kernel.org/tip/301d724aa19add1c0cf3ec8cad0d10151d30393f Author: Wang Nan AuthorDate: Mon, 13 Nov 2017 01:38:06 + Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 16 Nov 2017 14:49:58 -0300 perf tests: Set evlist of test__basic_mmap() to !overwrite In this test, a large ring buffer is required so all events can feed into, so overwrite or not is meaningless. Change to !overwrite so following commits can remove this argument. Signed-off-by: Wang Nan Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Link: http://lkml.kernel.org/r/20171113013809.212417-5-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/mmap-basic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 5a8bf31..91f10d6 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -94,7 +94,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse expected_nr_events[i] = 1 + rand() % 127; } - if (perf_evlist__mmap(evlist, 128, true) < 0) { + if (perf_evlist__mmap(evlist, 128, false) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist;
[PATCH 7/7] perf tools: Remove prot field in mmap param
After removing the concept of 'overwrite' in code level, now the prot is determinated by write_backward. There's no need to pass prot from perf_evlist__mmap_ex(). Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/util/evlist.c | 17 ++--- tools/perf/util/mmap.c | 4 ++-- tools/perf/util/mmap.h | 4 ++-- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4948d3d..0d713e0 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -799,28 +799,23 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, } static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, - struct mmap_params *_mp, int cpu_idx, + struct mmap_params *mp, int cpu_idx, int thread, int *_output, int *_output_backward) { struct perf_evsel *evsel; int revent; int evlist_cpu = cpu_map__cpu(evlist->cpus, cpu_idx); - struct mmap_params *mp; evlist__for_each_entry(evlist, evsel) { struct perf_mmap *maps = evlist->mmap; - struct mmap_params rdonly_mp; int *output = _output; int fd; int cpu; + int prot = PROT_READ; - mp = _mp; if (evsel->attr.write_backward) { output = _output_backward; maps = evlist->backward_mmap; - rdonly_mp = *_mp; - rdonly_mp.prot &= ~PROT_WRITE; - mp = _mp; if (!maps) { maps = perf_evlist__alloc_mmap(evlist); @@ -830,6 +825,8 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, if (evlist->bkw_mmap_state == BKW_MMAP_NOTREADY) perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING); } + } else { + prot |= PROT_WRITE; } if (evsel->system_wide && thread) @@ -844,7 +841,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, if (*output == -1) { *output = fd; - if (perf_mmap__mmap([idx], mp, *output) < 0) + if (perf_mmap__mmap([idx], mp, prot, *output) < 0) return -1; } else { if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0) @@ -1064,9 +1061,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, struct perf_evsel *evsel; const struct cpu_map *cpus = evlist->cpus; const struct thread_map *threads = evlist->threads; - struct mmap_params mp = { - .prot = PROT_READ | PROT_WRITE, - }; + struct mmap_params mp; if (!evlist->mmap) evlist->mmap = perf_evlist__alloc_mmap(evlist); diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 703ed41..40e91a0 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -219,7 +219,7 @@ void perf_mmap__munmap(struct perf_mmap *map) auxtrace_mmap__munmap(>auxtrace_mmap); } -int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd) +int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int prot, int fd) { /* * The last one will be done at perf_evlist__mmap_consume(), so that we @@ -237,7 +237,7 @@ int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd) refcount_set(>refcnt, 2); map->prev = 0; map->mask = mp->mask; - map->base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot, + map->base = mmap(NULL, perf_mmap__mmap_len(map), prot, MAP_SHARED, fd, 0); if (map->base == MAP_FAILED) { pr_debug2("failed to mmap perf event ring buffer, error %d\n", diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 2c3d291..1f6fcc6 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -53,11 +53,11 @@ enum bkw_mmap_state { }; struct mmap_params { - int prot, mask; + int mask; struct auxtrace_mmap_params auxtrace_mp; }; -int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd); +int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int prot, int fd); void perf_mmap__munmap(struct perf_mmap *map); void perf_mmap__get(struct perf_mmap *map); -- 2.10.1
[PATCH 7/7] perf tools: Remove prot field in mmap param
After removing the concept of 'overwrite' in code level, now the prot is determinated by write_backward. There's no need to pass prot from perf_evlist__mmap_ex(). Signed-off-by: Wang Nan --- tools/perf/util/evlist.c | 17 ++--- tools/perf/util/mmap.c | 4 ++-- tools/perf/util/mmap.h | 4 ++-- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4948d3d..0d713e0 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -799,28 +799,23 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, } static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, - struct mmap_params *_mp, int cpu_idx, + struct mmap_params *mp, int cpu_idx, int thread, int *_output, int *_output_backward) { struct perf_evsel *evsel; int revent; int evlist_cpu = cpu_map__cpu(evlist->cpus, cpu_idx); - struct mmap_params *mp; evlist__for_each_entry(evlist, evsel) { struct perf_mmap *maps = evlist->mmap; - struct mmap_params rdonly_mp; int *output = _output; int fd; int cpu; + int prot = PROT_READ; - mp = _mp; if (evsel->attr.write_backward) { output = _output_backward; maps = evlist->backward_mmap; - rdonly_mp = *_mp; - rdonly_mp.prot &= ~PROT_WRITE; - mp = _mp; if (!maps) { maps = perf_evlist__alloc_mmap(evlist); @@ -830,6 +825,8 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, if (evlist->bkw_mmap_state == BKW_MMAP_NOTREADY) perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING); } + } else { + prot |= PROT_WRITE; } if (evsel->system_wide && thread) @@ -844,7 +841,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, if (*output == -1) { *output = fd; - if (perf_mmap__mmap([idx], mp, *output) < 0) + if (perf_mmap__mmap([idx], mp, prot, *output) < 0) return -1; } else { if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0) @@ -1064,9 +1061,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, struct perf_evsel *evsel; const struct cpu_map *cpus = evlist->cpus; const struct thread_map *threads = evlist->threads; - struct mmap_params mp = { - .prot = PROT_READ | PROT_WRITE, - }; + struct mmap_params mp; if (!evlist->mmap) evlist->mmap = perf_evlist__alloc_mmap(evlist); diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 703ed41..40e91a0 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -219,7 +219,7 @@ void perf_mmap__munmap(struct perf_mmap *map) auxtrace_mmap__munmap(>auxtrace_mmap); } -int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd) +int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int prot, int fd) { /* * The last one will be done at perf_evlist__mmap_consume(), so that we @@ -237,7 +237,7 @@ int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd) refcount_set(>refcnt, 2); map->prev = 0; map->mask = mp->mask; - map->base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot, + map->base = mmap(NULL, perf_mmap__mmap_len(map), prot, MAP_SHARED, fd, 0); if (map->base == MAP_FAILED) { pr_debug2("failed to mmap perf event ring buffer, error %d\n", diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 2c3d291..1f6fcc6 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -53,11 +53,11 @@ enum bkw_mmap_state { }; struct mmap_params { - int prot, mask; + int mask; struct auxtrace_mmap_params auxtrace_mp; }; -int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd); +int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int prot, int fd); void perf_mmap__munmap(struct perf_mmap *map); void perf_mmap__get(struct perf_mmap *map); -- 2.10.1
[PATCH 5/7] perf tests: Set evlist of test__task_exit() to !overwrite
Changing ringbuffer to !overwrite in this task is harmless because this test uses a very low frequency (1) and using a very simple program (true). There should have only 3 events in the whole test. Overwriting is impossible to happen. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/tests/task-exit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index f0881d0..4fb6609 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -96,7 +96,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused goto out_delete_evlist; } - if (perf_evlist__mmap(evlist, 128, true) < 0) { + if (perf_evlist__mmap(evlist, 128, false) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; -- 2.10.1
[PATCH 1/7] perf mmap: Fix perf backward recording
perf record backward recording doesn't work as we expected: it never overwrite when ring buffer full. Test: (Run a busy printing task background like this: while True: print 123 send SIGUSR2 to perf to capture snapshot.) # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101520743 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521251 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521692 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101521936 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101520743 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521251 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521692 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 Timestamps are never change, but my background task is a dead loop, can easily overwhelme the ring buffer. This patch fix it by force unsetting PROT_WRITE for backward ring buffer, so all backward ring buffer become overwrite ring buffer. Test result: # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101285323 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290053 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290446 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101290837 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101285323 | head -n3 python 2545 [000] 11064.268083: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11064.268084: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11064.268086: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101290 | head -n3 failed to open ./perf.data.2017110101290: No such file or directory # ./perf script -i ./perf.data.2017110101290053 | head -n3 python 2545 [000] 11071.564062: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11071.564064: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11071.564066: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) # ./perf script -i ./perf.data.2017110101290 | head -n3 perf.data.2017110101290053 perf.data.2017110101290446 perf.data.2017110101290837 # ./perf script -i ./perf.data.2017110101290446 | head -n3 sshd 1321 [000] 11075.499473: raw_syscalls:sys_exit: NR 14 = 0 sshd 1321 [000] 11075.499474: raw_syscalls:sys_enter: NR 14 (2, 7ffe98899490, 0, 8, 0, 3000) sshd 1321 [000] 11075.499474: raw_syscalls:sys_exit: NR 14 = 0 # ./perf script -i ./perf.data.2017110101290837 | head -n3 python 2545 [000] 11079.280844: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11079.280847: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11079.280850: raw_syscalls:sys_exit: NR 1 = 4 Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/util/evlist.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c6c891e..4c5daba 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -799,22 +799,28 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, } static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, - struct mmap_params *mp, int cpu_idx, + struct mmap_params *_mp, int cpu_idx, int thread, int *_
[PATCH 0/7] perf tools: Clarify overwrite and backward, bugfix
Based on previous discussion, perf needs to support only two types of ringbuffer: read-write + forward, readonly + backward. This patchset completly removes the concept of 'overwrite' from code level, controls mapping permission using write_backward instead. Wang Nan (7): perf mmap: Fix perf backward recording perf tests: Set evlist of test__backward_ring_buffer() to !overwrite perf tests: Set evlist of test__sw_clock_freq() to !overwrite perf tests: Set evlist of test__basic_mmap() to !overwrite perf tests: Set evlist of test__task_exit() to !overwrite perf tools: Remove 'overwrite' concept from code level perf tools: Remove prot field in mmap param tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 4 ++-- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c| 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 21 ++--- tools/perf/util/evlist.h | 6 ++ tools/perf/util/mmap.c | 10 +- tools/perf/util/mmap.h | 6 +++--- tools/perf/util/python.c | 10 +- 20 files changed, 41 insertions(+), 44 deletions(-) -- 2.10.1
[PATCH 5/7] perf tests: Set evlist of test__task_exit() to !overwrite
Changing ringbuffer to !overwrite in this task is harmless because this test uses a very low frequency (1) and using a very simple program (true). There should have only 3 events in the whole test. Overwriting is impossible to happen. Signed-off-by: Wang Nan --- tools/perf/tests/task-exit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index f0881d0..4fb6609 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -96,7 +96,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused goto out_delete_evlist; } - if (perf_evlist__mmap(evlist, 128, true) < 0) { + if (perf_evlist__mmap(evlist, 128, false) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; -- 2.10.1
[PATCH 1/7] perf mmap: Fix perf backward recording
perf record backward recording doesn't work as we expected: it never overwrite when ring buffer full. Test: (Run a busy printing task background like this: while True: print 123 send SIGUSR2 to perf to capture snapshot.) # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101520743 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521251 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521692 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101521936 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101520743 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521251 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521692 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 Timestamps are never change, but my background task is a dead loop, can easily overwhelme the ring buffer. This patch fix it by force unsetting PROT_WRITE for backward ring buffer, so all backward ring buffer become overwrite ring buffer. Test result: # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101285323 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290053 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290446 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101290837 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101285323 | head -n3 python 2545 [000] 11064.268083: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11064.268084: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11064.268086: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101290 | head -n3 failed to open ./perf.data.2017110101290: No such file or directory # ./perf script -i ./perf.data.2017110101290053 | head -n3 python 2545 [000] 11071.564062: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11071.564064: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11071.564066: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) # ./perf script -i ./perf.data.2017110101290 | head -n3 perf.data.2017110101290053 perf.data.2017110101290446 perf.data.2017110101290837 # ./perf script -i ./perf.data.2017110101290446 | head -n3 sshd 1321 [000] 11075.499473: raw_syscalls:sys_exit: NR 14 = 0 sshd 1321 [000] 11075.499474: raw_syscalls:sys_enter: NR 14 (2, 7ffe98899490, 0, 8, 0, 3000) sshd 1321 [000] 11075.499474: raw_syscalls:sys_exit: NR 14 = 0 # ./perf script -i ./perf.data.2017110101290837 | head -n3 python 2545 [000] 11079.280844: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11079.280847: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11079.280850: raw_syscalls:sys_exit: NR 1 = 4 Signed-off-by: Wang Nan --- tools/perf/util/evlist.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c6c891e..4c5daba 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -799,22 +799,28 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, } static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, - struct mmap_params *mp, int cpu_idx, + struct mmap_params *_mp, int cpu_idx, int thread, int *_output, int *_output_backward
[PATCH 0/7] perf tools: Clarify overwrite and backward, bugfix
Based on previous discussion, perf needs to support only two types of ringbuffer: read-write + forward, readonly + backward. This patchset completly removes the concept of 'overwrite' from code level, controls mapping permission using write_backward instead. Wang Nan (7): perf mmap: Fix perf backward recording perf tests: Set evlist of test__backward_ring_buffer() to !overwrite perf tests: Set evlist of test__sw_clock_freq() to !overwrite perf tests: Set evlist of test__basic_mmap() to !overwrite perf tests: Set evlist of test__task_exit() to !overwrite perf tools: Remove 'overwrite' concept from code level perf tools: Remove prot field in mmap param tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 4 ++-- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c| 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 21 ++--- tools/perf/util/evlist.h | 6 ++ tools/perf/util/mmap.c | 10 +- tools/perf/util/mmap.h | 6 +++--- tools/perf/util/python.c | 10 +- 20 files changed, 41 insertions(+), 44 deletions(-) -- 2.10.1
[PATCH 3/7] perf tests: Set evlist of test__sw_clock_freq() to !overwrite
Unsetting overwrite when calling perf_evlist__mmap is harmless. This commit passes false to it, makes following commits eliminate the overwrite argument easier. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/tests/sw-clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index d88511f..c468e6c 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -77,7 +77,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) goto out_delete_evlist; } - err = perf_evlist__mmap(evlist, 128, true); + err = perf_evlist__mmap(evlist, 128, false); if (err < 0) { pr_debug("failed to mmap event: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); -- 2.10.1
[PATCH 3/7] perf tests: Set evlist of test__sw_clock_freq() to !overwrite
Unsetting overwrite when calling perf_evlist__mmap is harmless. This commit passes false to it, makes following commits eliminate the overwrite argument easier. Signed-off-by: Wang Nan --- tools/perf/tests/sw-clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index d88511f..c468e6c 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -77,7 +77,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) goto out_delete_evlist; } - err = perf_evlist__mmap(evlist, 128, true); + err = perf_evlist__mmap(evlist, 128, false); if (err < 0) { pr_debug("failed to mmap event: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); -- 2.10.1
[PATCH 4/7] perf tests: Set evlist of test__basic_mmap() to !overwrite
In this test, a large ring buffer is required so all events can feed into, so overwrite or not is meaningless. Change to !overwrite so following commits can remove this argument. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/tests/mmap-basic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index bc8a70e..667d696 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -93,7 +93,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse expected_nr_events[i] = 1 + rand() % 127; } - if (perf_evlist__mmap(evlist, 128, true) < 0) { + if (perf_evlist__mmap(evlist, 128, false) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; -- 2.10.1
[PATCH 2/7] perf tests: Set evlist of test__backward_ring_buffer() to !overwrite
Setting overwrite in perf_evlist__mmap() is meaningless because the event in this evlist is already have 'overwrite' postfix and goes to backward ring buffer automatically. Pass 'false' to perf_evlist__mmap() to make it similar to others. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/tests/backward-ring-buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index d233ad3..992c917 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -58,7 +58,7 @@ static int do_test(struct perf_evlist *evlist, int mmap_pages, int err; char sbuf[STRERR_BUFSIZE]; - err = perf_evlist__mmap(evlist, mmap_pages, true); + err = perf_evlist__mmap(evlist, mmap_pages, false); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); -- 2.10.1
[PATCH 4/7] perf tests: Set evlist of test__basic_mmap() to !overwrite
In this test, a large ring buffer is required so all events can feed into, so overwrite or not is meaningless. Change to !overwrite so following commits can remove this argument. Signed-off-by: Wang Nan --- tools/perf/tests/mmap-basic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index bc8a70e..667d696 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -93,7 +93,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse expected_nr_events[i] = 1 + rand() % 127; } - if (perf_evlist__mmap(evlist, 128, true) < 0) { + if (perf_evlist__mmap(evlist, 128, false) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; -- 2.10.1
[PATCH 2/7] perf tests: Set evlist of test__backward_ring_buffer() to !overwrite
Setting overwrite in perf_evlist__mmap() is meaningless because the event in this evlist is already have 'overwrite' postfix and goes to backward ring buffer automatically. Pass 'false' to perf_evlist__mmap() to make it similar to others. Signed-off-by: Wang Nan --- tools/perf/tests/backward-ring-buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index d233ad3..992c917 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -58,7 +58,7 @@ static int do_test(struct perf_evlist *evlist, int mmap_pages, int err; char sbuf[STRERR_BUFSIZE]; - err = perf_evlist__mmap(evlist, mmap_pages, true); + err = perf_evlist__mmap(evlist, mmap_pages, false); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); -- 2.10.1
[PATCH 6/7] perf tools: Remove 'overwrite' concept from code level
Since all 'overwrite' usage are cleaned and no one really use a readonly main ringbuffer, remove 'overwrite' from function arguments and evlist. The concept of 'overwrite' and 'write_backward' are cleanner than before: 1. In code level, there's no 'overwrite' concept. Each evlist has two ringbuffer groups. One is read-write/forward, another is readonly/backward. Don't support read-write/backward and readonly/forward. 2. In user interface, we keep '--overwrite' and translate it into write_backward in each event. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 4 ++-- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c| 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 14 ++ tools/perf/util/evlist.h | 6 ++ tools/perf/util/mmap.c | 6 +++--- tools/perf/util/mmap.h | 2 +- tools/perf/util/python.c | 10 +- 20 files changed, 33 insertions(+), 37 deletions(-) diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 5dd7efb..c7ea843 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -83,7 +83,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe CHECK__(perf_evlist__open(evlist)); - CHECK__(perf_evlist__mmap(evlist, UINT_MAX, false)); + CHECK__(perf_evlist__mmap(evlist, UINT_MAX)); pc = evlist->mmap[0].base; ret = perf_read_tsc_conversion(pc, ); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 0af4c09..e3e2a80 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1043,7 +1043,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) goto out; } - if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) { + if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) { ui__error("Failed to mmap the events: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); perf_evlist__close(evlist); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f4d9fc5..b3ef33f 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -300,7 +300,7 @@ static int record__mmap_evlist(struct record *rec, struct record_opts *opts = >opts; char msg[512]; - if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, + if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, opts->auxtrace_mmap_pages, opts->auxtrace_snapshot_mode) < 0) { if (errno == EPERM) { @@ -481,7 +481,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], evlist->overwrite, backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], backward, rec, record__pushfn) != 0) { rc = -1; goto out; } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 477a869..83d2ae2 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -902,7 +902,7 @@ static int perf_top__start_counters(struct perf_top *top) } } - if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) { + if (perf_evlist__mmap(evlist, opts->mmap_pages) < 0) { ui__error("Failed to mmap with %d (%s)\n", errno, str_error_r(errno, msg, sizeof(msg))); goto out_err; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c373f9a..c3f2f98 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2404,7 +2404,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_error_apply_fil
[PATCH 6/7] perf tools: Remove 'overwrite' concept from code level
Since all 'overwrite' usage are cleaned and no one really use a readonly main ringbuffer, remove 'overwrite' from function arguments and evlist. The concept of 'overwrite' and 'write_backward' are cleanner than before: 1. In code level, there's no 'overwrite' concept. Each evlist has two ringbuffer groups. One is read-write/forward, another is readonly/backward. Don't support read-write/backward and readonly/forward. 2. In user interface, we keep '--overwrite' and translate it into write_backward in each event. Signed-off-by: Wang Nan --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 4 ++-- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c| 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 14 ++ tools/perf/util/evlist.h | 6 ++ tools/perf/util/mmap.c | 6 +++--- tools/perf/util/mmap.h | 2 +- tools/perf/util/python.c | 10 +- 20 files changed, 33 insertions(+), 37 deletions(-) diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 5dd7efb..c7ea843 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -83,7 +83,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe CHECK__(perf_evlist__open(evlist)); - CHECK__(perf_evlist__mmap(evlist, UINT_MAX, false)); + CHECK__(perf_evlist__mmap(evlist, UINT_MAX)); pc = evlist->mmap[0].base; ret = perf_read_tsc_conversion(pc, ); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 0af4c09..e3e2a80 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1043,7 +1043,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) goto out; } - if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) { + if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) { ui__error("Failed to mmap the events: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); perf_evlist__close(evlist); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f4d9fc5..b3ef33f 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -300,7 +300,7 @@ static int record__mmap_evlist(struct record *rec, struct record_opts *opts = >opts; char msg[512]; - if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, + if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, opts->auxtrace_mmap_pages, opts->auxtrace_snapshot_mode) < 0) { if (errno == EPERM) { @@ -481,7 +481,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli struct auxtrace_mmap *mm = [i].auxtrace_mmap; if (maps[i].base) { - if (perf_mmap__push([i], evlist->overwrite, backward, rec, record__pushfn) != 0) { + if (perf_mmap__push([i], backward, rec, record__pushfn) != 0) { rc = -1; goto out; } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 477a869..83d2ae2 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -902,7 +902,7 @@ static int perf_top__start_counters(struct perf_top *top) } } - if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) { + if (perf_evlist__mmap(evlist, opts->mmap_pages) < 0) { ui__error("Failed to mmap with %d (%s)\n", errno, str_error_r(errno, msg, sizeof(msg))); goto out_err; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c373f9a..c3f2f98 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2404,7 +2404,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_error_apply_filters; - err
[RESEND PATCH] mm, oom_reaper: gather each vma to prevent leaking TLB entry
tlb_gather_mmu(, mm, 0, -1) means gathering the whole virtual memory space. In this case, tlb->fullmm is true. Some archs like arm64 doesn't flush TLB when tlb->fullmm is true: commit 5a7862e83000 ("arm64: tlbflush: avoid flushing when fullmm == 1"). Which makes leaking of tlb entries. Will clarifies his patch: > Basically, we tag each address space with an ASID (PCID on x86) which > is resident in the TLB. This means we can elide TLB invalidation when > pulling down a full mm because we won't ever assign that ASID to another mm > without doing TLB invalidation elsewhere (which actually just nukes the > whole TLB). > > I think that means that we could potentially not fault on a kernel uaccess, > because we could hit in the TLB. There could be a window between complete_signal() sending IPI to other cores and all threads sharing this mm are really kicked off from cores. In this window, the oom reaper may calls tlb_flush_mmu_tlbonly() to flush TLB then frees pages. However, due to the above problem, the TLB entries are not really flushed on arm64. Other threads are possible to access these pages through TLB entries. Moreover, a copy_to_user() can also write to these pages without generating page fault, causes use-after-free bugs. This patch gathers each vma instead of gathering full vm space. In this case tlb->fullmm is not true. The behavior of oom reaper become similar to munmapping before do_exit, which should be safe for all archs. Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Bob Liu <liub...@huawei.com> Cc: Andrew Morton <a...@linux-foundation.org> Cc: Michal Hocko <mho...@suse.com> Cc: David Rientjes <rient...@google.com> Cc: Ingo Molnar <mi...@kernel.org> Cc: Roman Gushchin <g...@fb.com> Cc: Konstantin Khlebnikov <khlebni...@yandex-team.ru> Cc: Andrea Arcangeli <aarca...@redhat.com> --- mm/oom_kill.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index dee0f75..18c5b35 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -532,7 +532,6 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) */ set_bit(MMF_UNSTABLE, >flags); - tlb_gather_mmu(, mm, 0, -1); for (vma = mm->mmap ; vma; vma = vma->vm_next) { if (!can_madv_dontneed_vma(vma)) continue; @@ -547,11 +546,13 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) * we do not want to block exit_mmap by keeping mm ref * count elevated without a good reason. */ - if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) + if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) { + tlb_gather_mmu(, mm, vma->vm_start, vma->vm_end); unmap_page_range(, vma, vma->vm_start, vma->vm_end, NULL); + tlb_finish_mmu(, vma->vm_start, vma->vm_end); + } } - tlb_finish_mmu(, 0, -1); pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n", task_pid_nr(tsk), tsk->comm, K(get_mm_counter(mm, MM_ANONPAGES)), -- 2.10.1
[RESEND PATCH] mm, oom_reaper: gather each vma to prevent leaking TLB entry
tlb_gather_mmu(, mm, 0, -1) means gathering the whole virtual memory space. In this case, tlb->fullmm is true. Some archs like arm64 doesn't flush TLB when tlb->fullmm is true: commit 5a7862e83000 ("arm64: tlbflush: avoid flushing when fullmm == 1"). Which makes leaking of tlb entries. Will clarifies his patch: > Basically, we tag each address space with an ASID (PCID on x86) which > is resident in the TLB. This means we can elide TLB invalidation when > pulling down a full mm because we won't ever assign that ASID to another mm > without doing TLB invalidation elsewhere (which actually just nukes the > whole TLB). > > I think that means that we could potentially not fault on a kernel uaccess, > because we could hit in the TLB. There could be a window between complete_signal() sending IPI to other cores and all threads sharing this mm are really kicked off from cores. In this window, the oom reaper may calls tlb_flush_mmu_tlbonly() to flush TLB then frees pages. However, due to the above problem, the TLB entries are not really flushed on arm64. Other threads are possible to access these pages through TLB entries. Moreover, a copy_to_user() can also write to these pages without generating page fault, causes use-after-free bugs. This patch gathers each vma instead of gathering full vm space. In this case tlb->fullmm is not true. The behavior of oom reaper become similar to munmapping before do_exit, which should be safe for all archs. Signed-off-by: Wang Nan Cc: Bob Liu Cc: Andrew Morton Cc: Michal Hocko Cc: David Rientjes Cc: Ingo Molnar Cc: Roman Gushchin Cc: Konstantin Khlebnikov Cc: Andrea Arcangeli --- mm/oom_kill.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index dee0f75..18c5b35 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -532,7 +532,6 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) */ set_bit(MMF_UNSTABLE, >flags); - tlb_gather_mmu(, mm, 0, -1); for (vma = mm->mmap ; vma; vma = vma->vm_next) { if (!can_madv_dontneed_vma(vma)) continue; @@ -547,11 +546,13 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) * we do not want to block exit_mmap by keeping mm ref * count elevated without a good reason. */ - if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) + if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) { + tlb_gather_mmu(, mm, vma->vm_start, vma->vm_end); unmap_page_range(, vma, vma->vm_start, vma->vm_end, NULL); + tlb_finish_mmu(, vma->vm_start, vma->vm_end); + } } - tlb_finish_mmu(, 0, -1); pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n", task_pid_nr(tsk), tsk->comm, K(get_mm_counter(mm, MM_ANONPAGES)), -- 2.10.1
[RFC PATCH] mm, oom_reaper: gather each vma to prevent leaking TLB entry
tlb_gather_mmu(, mm, 0, -1) means gathering all virtual memory space. In this case, tlb->fullmm is true. Some archs like arm64 doesn't flush TLB when tlb->fullmm is true: commit 5a7862e83000 ("arm64: tlbflush: avoid flushing when fullmm == 1"). Which makes leaking of tlb entries. For example, when oom_reaper selects a task and reaps its virtual memory space, another thread in this task group may still running on another core and access these already freed memory through tlb entries. This patch gather each vma instead of gathering full vm space, tlb->fullmm is not true. The behavior of oom reaper become similar to munmapping before do_exit, which should be safe for all archs. Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Bob Liu <liub...@huawei.com> Cc: Michal Hocko <mho...@suse.com> Cc: Andrew Morton <a...@linux-foundation.org> Cc: Michal Hocko <mho...@suse.com> Cc: David Rientjes <rient...@google.com> Cc: Ingo Molnar <mi...@kernel.org> Cc: Roman Gushchin <g...@fb.com> Cc: Konstantin Khlebnikov <khlebni...@yandex-team.ru> Cc: Andrea Arcangeli <aarca...@redhat.com> --- mm/oom_kill.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index dee0f75..18c5b35 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -532,7 +532,6 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) */ set_bit(MMF_UNSTABLE, >flags); - tlb_gather_mmu(, mm, 0, -1); for (vma = mm->mmap ; vma; vma = vma->vm_next) { if (!can_madv_dontneed_vma(vma)) continue; @@ -547,11 +546,13 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) * we do not want to block exit_mmap by keeping mm ref * count elevated without a good reason. */ - if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) + if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) { + tlb_gather_mmu(, mm, vma->vm_start, vma->vm_end); unmap_page_range(, vma, vma->vm_start, vma->vm_end, NULL); + tlb_finish_mmu(, vma->vm_start, vma->vm_end); + } } - tlb_finish_mmu(, 0, -1); pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n", task_pid_nr(tsk), tsk->comm, K(get_mm_counter(mm, MM_ANONPAGES)), -- 2.10.1
[RFC PATCH] mm, oom_reaper: gather each vma to prevent leaking TLB entry
tlb_gather_mmu(, mm, 0, -1) means gathering all virtual memory space. In this case, tlb->fullmm is true. Some archs like arm64 doesn't flush TLB when tlb->fullmm is true: commit 5a7862e83000 ("arm64: tlbflush: avoid flushing when fullmm == 1"). Which makes leaking of tlb entries. For example, when oom_reaper selects a task and reaps its virtual memory space, another thread in this task group may still running on another core and access these already freed memory through tlb entries. This patch gather each vma instead of gathering full vm space, tlb->fullmm is not true. The behavior of oom reaper become similar to munmapping before do_exit, which should be safe for all archs. Signed-off-by: Wang Nan Cc: Bob Liu Cc: Michal Hocko Cc: Andrew Morton Cc: Michal Hocko Cc: David Rientjes Cc: Ingo Molnar Cc: Roman Gushchin Cc: Konstantin Khlebnikov Cc: Andrea Arcangeli --- mm/oom_kill.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index dee0f75..18c5b35 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -532,7 +532,6 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) */ set_bit(MMF_UNSTABLE, >flags); - tlb_gather_mmu(, mm, 0, -1); for (vma = mm->mmap ; vma; vma = vma->vm_next) { if (!can_madv_dontneed_vma(vma)) continue; @@ -547,11 +546,13 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) * we do not want to block exit_mmap by keeping mm ref * count elevated without a good reason. */ - if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) + if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) { + tlb_gather_mmu(, mm, vma->vm_start, vma->vm_end); unmap_page_range(, vma, vma->vm_start, vma->vm_end, NULL); + tlb_finish_mmu(, vma->vm_start, vma->vm_end); + } } - tlb_finish_mmu(, 0, -1); pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n", task_pid_nr(tsk), tsk->comm, K(get_mm_counter(mm, MM_ANONPAGES)), -- 2.10.1
[PATCH 2/2] perf record: Replace 'overwrite' by 'flightrecorder' for better naming
The meaning of perf record's "overwrite" option and many "overwrite" in source code are not clear. In perf's code, the 'overwrite' has 2 meanings: 1. Make ringbuffer readonly (perf_evlist__mmap_ex's argument). 2. Set evsel's "backward" attribute (in apply_config_terms). perf record doesn't use meaning 1 at all, but have a overwrite option, its real meaning is setting backward. This patch separates these two concepts, introduce 'flightrecorder' mode which is what we really want. It combines these 2 concept together, wraps them into a record mode. In flight recorder mode, perf only dumps data before something happen. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/Documentation/perf-record.txt | 8 tools/perf/builtin-record.c | 4 ++-- tools/perf/perf.h| 2 +- tools/perf/util/evsel.c | 6 +++--- tools/perf/util/evsel.h | 4 ++-- tools/perf/util/parse-events.c | 20 ++-- tools/perf/util/parse-events.h | 4 ++-- tools/perf/util/parse-events.l | 4 ++-- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 5a626ef..463c2d3 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -467,19 +467,19 @@ the beginning of record, collect them during finalizing an output file. The collected non-sample events reflects the status of the system when record is finished. ---overwrite:: +--flight-recorder:: Makes all events use an overwritable ring buffer. An overwritable ring buffer works like a flight recorder: when it gets full, the kernel will overwrite the oldest records, that thus will never make it to the perf.data file. -When '--overwrite' and '--switch-output' are used perf records and drops +When '--flight-recorder' and '--switch-output' are used perf records and drops events until it receives a signal, meaning that something unusual was detected that warrants taking a snapshot of the most current events, those fitting in the ring buffer at that moment. -'overwrite' attribute can also be set or canceled for an event using -config terms. For example: 'cycles/overwrite/' and 'instructions/no-overwrite/'. +'flightrecorder' attribute can also be set or canceled separately for an event using +config terms. For example: 'cycles/flightrecorder/' and 'instructions/no-flightrecorder/'. Implies --tail-synthesize. diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f4d9fc5..315ea09 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1489,7 +1489,7 @@ static struct option __record_options[] = { "child tasks do not inherit counters"), OPT_BOOLEAN(0, "tail-synthesize", _synthesize, "synthesize non-sample events at the end of output"), - OPT_BOOLEAN(0, "overwrite", , "use overwrite mode"), + OPT_BOOLEAN(0, "flight-recoder", _recorder, "use flight recoder mode"), OPT_UINTEGER('F', "freq", _freq, "profile at this frequency"), OPT_CALLBACK('m', "mmap-pages", , "pages[,pages]", "number of mmap data pages and AUX area tracing mmap pages", @@ -1733,7 +1733,7 @@ int cmd_record(int argc, const char **argv) } } - if (record.opts.overwrite) + if (record.opts.flight_recorder) record.opts.tail_synthesize = true; if (rec->evlist->nr_entries == 0 && diff --git a/tools/perf/perf.h b/tools/perf/perf.h index fbb0a9c..a7f7618 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -57,7 +57,7 @@ struct record_opts { bool all_kernel; bool all_user; bool tail_synthesize; - bool overwrite; + bool flight_recorder; bool ignore_missing_thread; unsigned int freq; unsigned int mmap_pages; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index f894893..0e1e8e8 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -772,8 +772,8 @@ static void apply_config_terms(struct perf_evsel *evsel, */ attr->inherit = term->val.inherit ? 1 : 0; break; - case PERF_EVSEL__CONFIG_TERM_OVERWRITE: - attr->write_backward = term->val.overwrite ? 1 : 0; + case PERF_EVSEL__CONFIG_TERM_FLIGHTRECORDER: + attr->write_backward = term->val.flightrecorder ? 1 : 0; break; default: break; @@ -856,7 +856,7 @@ void perf_evs
[PATCH 0/2] perf record: Fix --overwrite and clarify concepts
Kan reports that 'perf record --overwrite' not working as it should be. Patch 1/2 fix a bug, map backward events to readonly ring buffer so kernel can overwrite that ring buffer. Patch 2/2 clarify concepts of 'overwrite' and 'backward' in the source code by introducing the concept of 'flightrecorder' and convert many 'overwrite' to it to clarify that what we really want is a perf record flightrecorder mode, not only mapping the ring buffer overwritable. Wang Nan (2): perf mmap: Fix perf backward recording perf record: Replace 'overwrite' by 'flightrecorder' for better naming tools/perf/Documentation/perf-record.txt | 8 tools/perf/builtin-record.c | 4 ++-- tools/perf/perf.h| 2 +- tools/perf/util/evlist.c | 8 +++- tools/perf/util/evsel.c | 6 +++--- tools/perf/util/evsel.h | 4 ++-- tools/perf/util/parse-events.c | 20 ++-- tools/perf/util/parse-events.h | 4 ++-- tools/perf/util/parse-events.l | 4 ++-- 9 files changed, 33 insertions(+), 27 deletions(-) -- 2.10.1
[PATCH 2/2] perf record: Replace 'overwrite' by 'flightrecorder' for better naming
The meaning of perf record's "overwrite" option and many "overwrite" in source code are not clear. In perf's code, the 'overwrite' has 2 meanings: 1. Make ringbuffer readonly (perf_evlist__mmap_ex's argument). 2. Set evsel's "backward" attribute (in apply_config_terms). perf record doesn't use meaning 1 at all, but have a overwrite option, its real meaning is setting backward. This patch separates these two concepts, introduce 'flightrecorder' mode which is what we really want. It combines these 2 concept together, wraps them into a record mode. In flight recorder mode, perf only dumps data before something happen. Signed-off-by: Wang Nan --- tools/perf/Documentation/perf-record.txt | 8 tools/perf/builtin-record.c | 4 ++-- tools/perf/perf.h| 2 +- tools/perf/util/evsel.c | 6 +++--- tools/perf/util/evsel.h | 4 ++-- tools/perf/util/parse-events.c | 20 ++-- tools/perf/util/parse-events.h | 4 ++-- tools/perf/util/parse-events.l | 4 ++-- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 5a626ef..463c2d3 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -467,19 +467,19 @@ the beginning of record, collect them during finalizing an output file. The collected non-sample events reflects the status of the system when record is finished. ---overwrite:: +--flight-recorder:: Makes all events use an overwritable ring buffer. An overwritable ring buffer works like a flight recorder: when it gets full, the kernel will overwrite the oldest records, that thus will never make it to the perf.data file. -When '--overwrite' and '--switch-output' are used perf records and drops +When '--flight-recorder' and '--switch-output' are used perf records and drops events until it receives a signal, meaning that something unusual was detected that warrants taking a snapshot of the most current events, those fitting in the ring buffer at that moment. -'overwrite' attribute can also be set or canceled for an event using -config terms. For example: 'cycles/overwrite/' and 'instructions/no-overwrite/'. +'flightrecorder' attribute can also be set or canceled separately for an event using +config terms. For example: 'cycles/flightrecorder/' and 'instructions/no-flightrecorder/'. Implies --tail-synthesize. diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f4d9fc5..315ea09 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1489,7 +1489,7 @@ static struct option __record_options[] = { "child tasks do not inherit counters"), OPT_BOOLEAN(0, "tail-synthesize", _synthesize, "synthesize non-sample events at the end of output"), - OPT_BOOLEAN(0, "overwrite", , "use overwrite mode"), + OPT_BOOLEAN(0, "flight-recoder", _recorder, "use flight recoder mode"), OPT_UINTEGER('F', "freq", _freq, "profile at this frequency"), OPT_CALLBACK('m', "mmap-pages", , "pages[,pages]", "number of mmap data pages and AUX area tracing mmap pages", @@ -1733,7 +1733,7 @@ int cmd_record(int argc, const char **argv) } } - if (record.opts.overwrite) + if (record.opts.flight_recorder) record.opts.tail_synthesize = true; if (rec->evlist->nr_entries == 0 && diff --git a/tools/perf/perf.h b/tools/perf/perf.h index fbb0a9c..a7f7618 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -57,7 +57,7 @@ struct record_opts { bool all_kernel; bool all_user; bool tail_synthesize; - bool overwrite; + bool flight_recorder; bool ignore_missing_thread; unsigned int freq; unsigned int mmap_pages; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index f894893..0e1e8e8 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -772,8 +772,8 @@ static void apply_config_terms(struct perf_evsel *evsel, */ attr->inherit = term->val.inherit ? 1 : 0; break; - case PERF_EVSEL__CONFIG_TERM_OVERWRITE: - attr->write_backward = term->val.overwrite ? 1 : 0; + case PERF_EVSEL__CONFIG_TERM_FLIGHTRECORDER: + attr->write_backward = term->val.flightrecorder ? 1 : 0; break; default: break; @@ -856,7 +856,7 @@ void perf_evsel__config(struct pe
[PATCH 0/2] perf record: Fix --overwrite and clarify concepts
Kan reports that 'perf record --overwrite' not working as it should be. Patch 1/2 fix a bug, map backward events to readonly ring buffer so kernel can overwrite that ring buffer. Patch 2/2 clarify concepts of 'overwrite' and 'backward' in the source code by introducing the concept of 'flightrecorder' and convert many 'overwrite' to it to clarify that what we really want is a perf record flightrecorder mode, not only mapping the ring buffer overwritable. Wang Nan (2): perf mmap: Fix perf backward recording perf record: Replace 'overwrite' by 'flightrecorder' for better naming tools/perf/Documentation/perf-record.txt | 8 tools/perf/builtin-record.c | 4 ++-- tools/perf/perf.h| 2 +- tools/perf/util/evlist.c | 8 +++- tools/perf/util/evsel.c | 6 +++--- tools/perf/util/evsel.h | 4 ++-- tools/perf/util/parse-events.c | 20 ++-- tools/perf/util/parse-events.h | 4 ++-- tools/perf/util/parse-events.l | 4 ++-- 9 files changed, 33 insertions(+), 27 deletions(-) -- 2.10.1
[PATCH 1/2] perf mmap: Fix perf backward recording
perf record backward recording doesn't work as we expected: it never overwrite when ring buffer full. Test: (Run a busy printing python task background like this: while True: print 123 send SIGUSR2 to perf to capture snapshot.) # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101520743 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521251 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521692 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101521936 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101520743 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521251 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521692 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 Timestamps are never change, but my background task is a dead loop, can easily overwhelme the ring buffer. This patch fix it by force unsetting PROT_WRITE for backward ring buffer, so all backward ring buffer become overwrite ring buffer. Test result: # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101285323 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290053 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290446 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101290837 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101285323 | head -n3 python 2545 [000] 11064.268083: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11064.268084: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11064.268086: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101290 | head -n3 failed to open ./perf.data.2017110101290: No such file or directory # ./perf script -i ./perf.data.2017110101290053 | head -n3 python 2545 [000] 11071.564062: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11071.564064: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11071.564066: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) # ./perf script -i ./perf.data.2017110101290 | head -n3 perf.data.2017110101290053 perf.data.2017110101290446 perf.data.2017110101290837 # ./perf script -i ./perf.data.2017110101290446 | head -n3 sshd 1321 [000] 11075.499473: raw_syscalls:sys_exit: NR 14 = 0 sshd 1321 [000] 11075.499474: raw_syscalls:sys_enter: NR 14 (2, 7ffe98899490, 0, 8, 0, 3000) sshd 1321 [000] 11075.499474: raw_syscalls:sys_exit: NR 14 = 0 # ./perf script -i ./perf.data.2017110101290837 | head -n3 python 2545 [000] 11079.280844: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11079.280847: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11079.280850: raw_syscalls:sys_exit: NR 1 = 4 Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/util/evlist.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c6c891e..4c5daba 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -799,22 +799,28 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, } static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, - struct mmap_params *mp, int cpu_idx, + struct mmap_params *_mp, int cpu_idx, int threa
[PATCH 1/2] perf mmap: Fix perf backward recording
perf record backward recording doesn't work as we expected: it never overwrite when ring buffer full. Test: (Run a busy printing python task background like this: while True: print 123 send SIGUSR2 to perf to capture snapshot.) # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101520743 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521251 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101521692 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101521936 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101520743 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521251 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101521692 | head -n3 perf 2717 [000] 12449.310785: raw_syscalls:sys_enter: NR 16 (5, 2400, 0, 59, 100, 0) perf 2717 [000] 12449.310790: raw_syscalls:sys_enter: NR 7 (4112340, 2, , 3df, 100, 0) python 2545 [000] 12449.310800: raw_syscalls:sys_exit: NR 1 = 4 Timestamps are never change, but my background task is a dead loop, can easily overwhelme the ring buffer. This patch fix it by force unsetting PROT_WRITE for backward ring buffer, so all backward ring buffer become overwrite ring buffer. Test result: # ./perf record --overwrite -e raw_syscalls:sys_enter -e raw_syscalls:sys_exit --exclude-perf -a --switch-output [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101285323 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290053 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017110101290446 ] ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2017110101290837 ] [ perf record: Captured and wrote 0.826 MB perf.data. ] # ./perf script -i ./perf.data.2017110101285323 | head -n3 python 2545 [000] 11064.268083: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11064.268084: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11064.268086: raw_syscalls:sys_exit: NR 1 = 4 # ./perf script -i ./perf.data.2017110101290 | head -n3 failed to open ./perf.data.2017110101290: No such file or directory # ./perf script -i ./perf.data.2017110101290053 | head -n3 python 2545 [000] 11071.564062: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11071.564064: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11071.564066: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) # ./perf script -i ./perf.data.2017110101290 | head -n3 perf.data.2017110101290053 perf.data.2017110101290446 perf.data.2017110101290837 # ./perf script -i ./perf.data.2017110101290446 | head -n3 sshd 1321 [000] 11075.499473: raw_syscalls:sys_exit: NR 14 = 0 sshd 1321 [000] 11075.499474: raw_syscalls:sys_enter: NR 14 (2, 7ffe98899490, 0, 8, 0, 3000) sshd 1321 [000] 11075.499474: raw_syscalls:sys_exit: NR 14 = 0 # ./perf script -i ./perf.data.2017110101290837 | head -n3 python 2545 [000] 11079.280844: raw_syscalls:sys_exit: NR 1 = 4 python 2545 [000] 11079.280847: raw_syscalls:sys_enter: NR 1 (1, 12cc330, 4, 7fc237280370, 7fc2373d0700, 2c7b0) python 2545 [000] 11079.280850: raw_syscalls:sys_exit: NR 1 = 4 Signed-off-by: Wang Nan --- tools/perf/util/evlist.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c6c891e..4c5daba 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -799,22 +799,28 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, } static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, - struct mmap_params *mp, int cpu_idx, + struct mmap_params *_mp, int cpu_idx, int thread, int *_output, int
[PATCH] perf tool: Don't discard prev in backward mode
Perf record can switch output. The new output should only store the data after switching. However, in overwrite backward mode, the new output still have the data from old output. That also brings extra overhead. At the end of mmap_read, the position of processed ring buffer is saved in md->prev. Next mmap_read should be end in md->prev if it is not overwriten. That avoids to process duplicate data. However, the md->prev is discarded. So next mmap_read has to process whole valid ring buffer, which probably include the old processed data. Avoid calling backward_rb_find_range() when md->prev is still available. Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Liang Kan <kan.li...@intel.com> --- tools/perf/util/mmap.c | 33 +++-- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 9fe5f9c..df1de55 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -287,18 +287,6 @@ static int backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 return -1; } -static int rb_find_range(void *data, int mask, u64 head, u64 old, -u64 *start, u64 *end, bool backward) -{ - if (!backward) { - *start = old; - *end = head; - return 0; - } - - return backward_rb_find_range(data, mask, head, start, end); -} - int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, void *to, int push(void *to, void *buf, size_t size)) { @@ -310,19 +298,28 @@ int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, void *buf; int rc = 0; - if (rb_find_range(data, md->mask, head, old, , , backward)) - return -1; + start = backward ? head : old; + end = backward ? old : head; if (start == end) return 0; size = end - start; if (size > (unsigned long)(md->mask) + 1) { - WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); + if (!backward) { + WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); - md->prev = head; - perf_mmap__consume(md, overwrite || backward); - return 0; + md->prev = head; + perf_mmap__consume(md, overwrite || backward); + return 0; + } + + /* +* Backward ring buffer is full. We still have a chance to read +* most of data from it. +*/ + if (backward_rb_find_range(data, md->mask, head, , )) + return -1; } if ((start & md->mask) + size != (end & md->mask)) { -- 2.9.3
[PATCH] perf tool: Don't discard prev in backward mode
Perf record can switch output. The new output should only store the data after switching. However, in overwrite backward mode, the new output still have the data from old output. That also brings extra overhead. At the end of mmap_read, the position of processed ring buffer is saved in md->prev. Next mmap_read should be end in md->prev if it is not overwriten. That avoids to process duplicate data. However, the md->prev is discarded. So next mmap_read has to process whole valid ring buffer, which probably include the old processed data. Avoid calling backward_rb_find_range() when md->prev is still available. Signed-off-by: Wang Nan Cc: Liang Kan --- tools/perf/util/mmap.c | 33 +++-- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 9fe5f9c..df1de55 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -287,18 +287,6 @@ static int backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 return -1; } -static int rb_find_range(void *data, int mask, u64 head, u64 old, -u64 *start, u64 *end, bool backward) -{ - if (!backward) { - *start = old; - *end = head; - return 0; - } - - return backward_rb_find_range(data, mask, head, start, end); -} - int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, void *to, int push(void *to, void *buf, size_t size)) { @@ -310,19 +298,28 @@ int perf_mmap__push(struct perf_mmap *md, bool overwrite, bool backward, void *buf; int rc = 0; - if (rb_find_range(data, md->mask, head, old, , , backward)) - return -1; + start = backward ? head : old; + end = backward ? old : head; if (start == end) return 0; size = end - start; if (size > (unsigned long)(md->mask) + 1) { - WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); + if (!backward) { + WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); - md->prev = head; - perf_mmap__consume(md, overwrite || backward); - return 0; + md->prev = head; + perf_mmap__consume(md, overwrite || backward); + return 0; + } + + /* +* Backward ring buffer is full. We still have a chance to read +* most of data from it. +*/ + if (backward_rb_find_range(data, md->mask, head, , )) + return -1; } if ((start & md->mask) + size != (end & md->mask)) { -- 2.9.3
[PATCH] perf tools: fix: Force backward ring buffer mapped readonly
perf record's --overwrite option doesn't work as we expect. For example: $ ~/linux/tools/perf$ sudo rm ./perf.data* rm: cannot remove './perf.data*': No such file or directory : ~/linux/tools/perf$ sudo ./perf record -m 4 -e raw_syscalls:* -g --overwrite \ --switch-output=1s --tail-synthesize dd if=/dev/zero of=/dev/null [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221460002 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221460102 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221460202 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221460302 ] ^C[ perf record: Woken up 1 times to write data ] 2066346+0 records in 2066346+0 records out 1057969152 bytes (1.1 GB, 1009 MiB) copied, 4.25983 s, 248 MB/s [ perf record: Dump perf.data.2017101221460332 ] [ perf record: Captured and wrote 0.034 MB perf.data. ] $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221460002 | head -n 1 dd 3918 [006] 182589.668954: raw_syscalls:sys_exit: NR 59 = 0 $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221460102 | head -n 1 dd 3918 [006] 182589.668954: raw_syscalls:sys_exit: NR 59 = 0 $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221460202 | head -n 1 dd 3918 [006] 182589.668954: raw_syscalls:sys_exit: NR 59 = 0 $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221460302 | head -n 1 dd 3918 [006] 182589.668954: raw_syscalls:sys_exit: NR 59 = 0 In the above example we get same records from the backward ring buffer all the time. Overwriting is not triggered. This commit maps backward ring buffers readonly, make it overwritable. It is safe because we assume backward ring buffer always overwritable in other part of code. After applying this patch: $ ~/linux/tools/perf$ sudo ./perf record -m 4 -e raw_syscalls:* -g --overwrite \ --switch-output=1s --tail-synthesize dd if=/dev/zero of=/dev/null [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221540350 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221540451 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221540551 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221540651 ] ^C[ perf record: Woken up 1 times to write data ] 1604606+0 records in 1604605+0 records out 821557760 bytes (822 MB, 783 MiB) copied, 4.42736 s, 186 MB/s [ perf record: Dump perf.data.2017101221540700 ] [ perf record: Captured and wrote 0.034 MB perf.data. ] $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221540350 | head -n 1 dd 5126 [003] 183074.104581: raw_syscalls:sys_exit: NR 0 = 512 $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221540451 | head -n 1 dd 5126 [003] 183075.106496: raw_syscalls:sys_exit: NR 1 = 512 $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221540551 | head -n 1 dd 5126 [003] 183076.108093: raw_syscalls:sys_enter: NR 1 (1, af8000, 200, 871, 0, af8060) $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221540651 | head -n 1 dd 5126 [003] 183077.109676: raw_syscalls:sys_exit: NR 1 = 512 Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Liang Kan <kan.li...@intel.com> Cc: Arnaldo Carvalho de Melo <a...@kernel.org> Cc: Peter Zijlstra <pet...@infradead.org> Cc: Ingo Molnar <mi...@kernel.org> Cc: Jiri Olsa <jo...@kernel.org> Cc: Namhyung Kim <namhy...@kernel.org> Cc: Alexander Shishkin <alexander.shish...@linux.intel.com> Cc: Adrian Hunter <adrian.hun...@intel.com> Cc: Andi Kleen <a...@linux.intel.com> Cc: Li Zefan <lize...@huawei.com> --- tools/perf/util/evlist.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c6c891e..a86b0d2 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -799,12 +799,14 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, } static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, - struct mmap_params *mp, int cpu_idx, + struct mmap_params *_mp, int cpu_idx, int thread, int *_output, int *_output_backward) { struct perf_evsel *evsel; int revent; int evlist_cpu = cpu_map__cpu(evlist->cpus, cpu_idx); + struct mmap_params *mp = _mp; + struct mmap_params backward_mp; evlist__for_each_entry(evlist, evse
[PATCH] perf tools: fix: Force backward ring buffer mapped readonly
perf record's --overwrite option doesn't work as we expect. For example: $ ~/linux/tools/perf$ sudo rm ./perf.data* rm: cannot remove './perf.data*': No such file or directory : ~/linux/tools/perf$ sudo ./perf record -m 4 -e raw_syscalls:* -g --overwrite \ --switch-output=1s --tail-synthesize dd if=/dev/zero of=/dev/null [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221460002 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221460102 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221460202 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221460302 ] ^C[ perf record: Woken up 1 times to write data ] 2066346+0 records in 2066346+0 records out 1057969152 bytes (1.1 GB, 1009 MiB) copied, 4.25983 s, 248 MB/s [ perf record: Dump perf.data.2017101221460332 ] [ perf record: Captured and wrote 0.034 MB perf.data. ] $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221460002 | head -n 1 dd 3918 [006] 182589.668954: raw_syscalls:sys_exit: NR 59 = 0 $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221460102 | head -n 1 dd 3918 [006] 182589.668954: raw_syscalls:sys_exit: NR 59 = 0 $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221460202 | head -n 1 dd 3918 [006] 182589.668954: raw_syscalls:sys_exit: NR 59 = 0 $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221460302 | head -n 1 dd 3918 [006] 182589.668954: raw_syscalls:sys_exit: NR 59 = 0 In the above example we get same records from the backward ring buffer all the time. Overwriting is not triggered. This commit maps backward ring buffers readonly, make it overwritable. It is safe because we assume backward ring buffer always overwritable in other part of code. After applying this patch: $ ~/linux/tools/perf$ sudo ./perf record -m 4 -e raw_syscalls:* -g --overwrite \ --switch-output=1s --tail-synthesize dd if=/dev/zero of=/dev/null [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221540350 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221540451 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221540551 ] [ perf record: dump data: Woken up 1 times ] [ perf record: Dump perf.data.2017101221540651 ] ^C[ perf record: Woken up 1 times to write data ] 1604606+0 records in 1604605+0 records out 821557760 bytes (822 MB, 783 MiB) copied, 4.42736 s, 186 MB/s [ perf record: Dump perf.data.2017101221540700 ] [ perf record: Captured and wrote 0.034 MB perf.data. ] $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221540350 | head -n 1 dd 5126 [003] 183074.104581: raw_syscalls:sys_exit: NR 0 = 512 $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221540451 | head -n 1 dd 5126 [003] 183075.106496: raw_syscalls:sys_exit: NR 1 = 512 $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221540551 | head -n 1 dd 5126 [003] 183076.108093: raw_syscalls:sys_enter: NR 1 (1, af8000, 200, 871, 0, af8060) $ ~/linux/tools/perf$ sudo ./perf script -i ./perf.data.2017101221540651 | head -n 1 dd 5126 [003] 183077.109676: raw_syscalls:sys_exit: NR 1 = 512 Signed-off-by: Wang Nan Cc: Liang Kan Cc: Arnaldo Carvalho de Melo Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Alexander Shishkin Cc: Adrian Hunter Cc: Andi Kleen Cc: Li Zefan --- tools/perf/util/evlist.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c6c891e..a86b0d2 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -799,12 +799,14 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, } static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, - struct mmap_params *mp, int cpu_idx, + struct mmap_params *_mp, int cpu_idx, int thread, int *_output, int *_output_backward) { struct perf_evsel *evsel; int revent; int evlist_cpu = cpu_map__cpu(evlist->cpus, cpu_idx); + struct mmap_params *mp = _mp; + struct mmap_params backward_mp; evlist__for_each_entry(evlist, evsel) { struct perf_mmap *maps = evlist->mmap; @@ -815,6 +817,9 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, if (evsel->attr.write_backward) { output = _output_backward; maps = evlist->b
[tip:perf/core] perf bpf: Fix endianness problem when loading parameters in prologue
Commit-ID: db26984a363e8b8e35783c402978e8acdf9041a5 Gitweb: http://git.kernel.org/tip/db26984a363e8b8e35783c402978e8acdf9041a5 Author: Wang Nan <wangn...@huawei.com> AuthorDate: Tue, 15 Aug 2017 11:21:59 +0200 Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Wed, 16 Aug 2017 10:31:11 -0300 perf bpf: Fix endianness problem when loading parameters in prologue Perf's BPF prologue generator unconditionally fetches 8 bytes for function parameters, which causes problems on big endian machines. Thomas gives a detailed analysis for this problem: http://lkml.kernel.org/r/968ebda5-abe4-8830-8d69-49f62529d...@linux.vnet.ibm.com 8< I investigated perf test BPF for s390x and have a question regarding the 38.3 subtest (bpf-prologue test) which fails on s390x. When I turn on trace_printk in tests/bpf-script-test-prologue.c I see this output in /sys/kernel/debug/tracing/trace: [root@s8360047 perf]# cat /sys/kernel/debug/tracing/trace perf-30229 [000] d..2 170161.535791: : f_mode 2001d offset:0 orig:0 perf-30229 [000] d..2 170161.535809: : f_mode 6001f offset:0 orig:0 perf-30229 [000] d..2 170161.535815: : f_mode 6001f offset:1 orig:0 perf-30229 [000] d..2 170161.535819: : f_mode 2001d offset:1 orig:0 perf-30229 [000] d..2 170161.535822: : f_mode 2001d offset:2 orig:1 perf-30229 [000] d..2 170161.535825: : f_mode 6001f offset:2 orig:1 perf-30229 [000] d..2 170161.535828: : f_mode 6001f offset:3 orig:1 perf-30229 [000] d..2 170161.535832: : f_mode 2001d offset:3 orig:1 perf-30229 [000] d..2 170161.535835: : f_mode 2001d offset:4 orig:0 perf-30229 [000] d..2 170161.535841: : f_mode 6001f offset:4 orig:0 [...] There are 3 parameters the eBPF program tests/bpf-script-test-prologue.c accesses: f_mode (member of struct file at offset 140) offset and orig. They are parameters of the lseek() system call triggered in this test case in function llseek_loop(). What is really strange is the value of f_mode. It is an 8 byte value, whereas in the probe event it is defined as a 4 byte value. The lower 4 bytes are all zero and do not belong to member f_mode. The correct value should be 2001d for read-only and 6001f for read-write open mode. Here is the output of the 'perf test -vv bpf' trace: Try to find probe point from debuginfo. Matched function: null_lseek [2d9310d] Probe point found: null_lseek+0 Searching 'file' variable in context. Converting variable file into trace event. converting f_mode in file f_mode type is unsigned int. Opening /sys/kernel/debug/tracing//README write=0 Searching 'offset' variable in context. Converting variable offset into trace event. offset type is long long int. Searching 'orig' variable in context. Converting variable orig into trace event. orig type is int. Found 1 probe_trace_events. Opening /sys/kernel/debug/tracing//kprobe_events write=1 Writing event: p:perf_bpf_probe/func _text+8794224 f_mode=+140(%r2):x32 8< This patch parses the type of each argument and converts data from memory to expected type. Now the test runs successfully on 4.13.0-rc5: [root@s8360046 perf]# ./perf test bpf 38: BPF filter : 38.1: Basic BPF filtering : Ok 38.2: BPF pinning : Ok 38.3: BPF prologue generation : Ok 38.4: BPF relocation checker : Ok [root@s8360046 perf]# Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Hendrik Brueckner <brueck...@linux.vnet.ibm.com> Link: http://lkml.kernel.org/r/20170815092159.31912-1-tmri...@linux.vnet.ibm.com Signed-off-by: Thomas-Mich Richter <tmri...@linux.vnet.ibm.com> Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/tests/bpf-script-test-prologue.c | 4 ++- tools/perf/util/bpf-prologue.c | 49 +++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index b4ebc75..43f1e16 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -26,9 +26,11 @@ static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = (void *) 6; SEC("func=null_lseek file->f_mode offset orig") -int bpf_func__null_lseek(void *ctx, int err, unsigned long f_mode, +int bpf_func__null_lseek(void *ctx, int err, unsigned long _f_mode, unsigned long offset, unsigned long orig) { + fmode_t f_mode = (fmode_t)_f_mode; + if (err) return 0; if (f_mode & FMODE_WRITE) diff --git a/tools/perf/util/bpf-prologue.c b/tools/perf/util/bpf-prologue.c index 1356220..827f914 100644 --- a/tools/perf/util/bpf-prol
[tip:perf/core] perf bpf: Fix endianness problem when loading parameters in prologue
Commit-ID: db26984a363e8b8e35783c402978e8acdf9041a5 Gitweb: http://git.kernel.org/tip/db26984a363e8b8e35783c402978e8acdf9041a5 Author: Wang Nan AuthorDate: Tue, 15 Aug 2017 11:21:59 +0200 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 16 Aug 2017 10:31:11 -0300 perf bpf: Fix endianness problem when loading parameters in prologue Perf's BPF prologue generator unconditionally fetches 8 bytes for function parameters, which causes problems on big endian machines. Thomas gives a detailed analysis for this problem: http://lkml.kernel.org/r/968ebda5-abe4-8830-8d69-49f62529d...@linux.vnet.ibm.com 8< I investigated perf test BPF for s390x and have a question regarding the 38.3 subtest (bpf-prologue test) which fails on s390x. When I turn on trace_printk in tests/bpf-script-test-prologue.c I see this output in /sys/kernel/debug/tracing/trace: [root@s8360047 perf]# cat /sys/kernel/debug/tracing/trace perf-30229 [000] d..2 170161.535791: : f_mode 2001d offset:0 orig:0 perf-30229 [000] d..2 170161.535809: : f_mode 6001f offset:0 orig:0 perf-30229 [000] d..2 170161.535815: : f_mode 6001f offset:1 orig:0 perf-30229 [000] d..2 170161.535819: : f_mode 2001d offset:1 orig:0 perf-30229 [000] d..2 170161.535822: : f_mode 2001d offset:2 orig:1 perf-30229 [000] d..2 170161.535825: : f_mode 6001f offset:2 orig:1 perf-30229 [000] d..2 170161.535828: : f_mode 6001f offset:3 orig:1 perf-30229 [000] d..2 170161.535832: : f_mode 2001d offset:3 orig:1 perf-30229 [000] d..2 170161.535835: : f_mode 2001d offset:4 orig:0 perf-30229 [000] d..2 170161.535841: : f_mode 6001f offset:4 orig:0 [...] There are 3 parameters the eBPF program tests/bpf-script-test-prologue.c accesses: f_mode (member of struct file at offset 140) offset and orig. They are parameters of the lseek() system call triggered in this test case in function llseek_loop(). What is really strange is the value of f_mode. It is an 8 byte value, whereas in the probe event it is defined as a 4 byte value. The lower 4 bytes are all zero and do not belong to member f_mode. The correct value should be 2001d for read-only and 6001f for read-write open mode. Here is the output of the 'perf test -vv bpf' trace: Try to find probe point from debuginfo. Matched function: null_lseek [2d9310d] Probe point found: null_lseek+0 Searching 'file' variable in context. Converting variable file into trace event. converting f_mode in file f_mode type is unsigned int. Opening /sys/kernel/debug/tracing//README write=0 Searching 'offset' variable in context. Converting variable offset into trace event. offset type is long long int. Searching 'orig' variable in context. Converting variable orig into trace event. orig type is int. Found 1 probe_trace_events. Opening /sys/kernel/debug/tracing//kprobe_events write=1 Writing event: p:perf_bpf_probe/func _text+8794224 f_mode=+140(%r2):x32 8< This patch parses the type of each argument and converts data from memory to expected type. Now the test runs successfully on 4.13.0-rc5: [root@s8360046 perf]# ./perf test bpf 38: BPF filter : 38.1: Basic BPF filtering : Ok 38.2: BPF pinning : Ok 38.3: BPF prologue generation : Ok 38.4: BPF relocation checker : Ok [root@s8360046 perf]# Signed-off-by: Wang Nan Cc: Hendrik Brueckner Link: http://lkml.kernel.org/r/20170815092159.31912-1-tmri...@linux.vnet.ibm.com Signed-off-by: Thomas-Mich Richter Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/bpf-script-test-prologue.c | 4 ++- tools/perf/util/bpf-prologue.c | 49 +++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index b4ebc75..43f1e16 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -26,9 +26,11 @@ static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = (void *) 6; SEC("func=null_lseek file->f_mode offset orig") -int bpf_func__null_lseek(void *ctx, int err, unsigned long f_mode, +int bpf_func__null_lseek(void *ctx, int err, unsigned long _f_mode, unsigned long offset, unsigned long orig) { + fmode_t f_mode = (fmode_t)_f_mode; + if (err) return 0; if (f_mode & FMODE_WRITE) diff --git a/tools/perf/util/bpf-prologue.c b/tools/perf/util/bpf-prologue.c index 1356220..827f914 100644 --- a/tools/perf/util/bpf-prologue.c +++ b/tools/perf/util/bpf-prologue.c @@ -58,6 +58,46 @@ check_pos(struct bpf_insn_pos *pos) return 0; } +/* + * Convert type string (u8/u16/u32/u64/
[PATCH] perf bpf: Fix endianness problem when loading parameters in prologue
Perf BPF prologue generator unconditionally fetches 8 bytes for function parameters, which causes problem on big endian machine. Thomas gives a detail analysis for this problem: http://lkml.kernel.org/r/968ebda5-abe4-8830-8d69-49f62529d...@linux.vnet.ibm.com This patch parses the type of each argument and converts data from memory to expected type. Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Arnaldo Carvalho de Melo <a...@kernel.org> Cc: Thomas Richter <tmri...@linux.vnet.ibm.com> Cc: Alexei Starovoitov <alexei.starovoi...@gmail.com> Cc: Hendrik Brueckner <brueck...@linux.vnet.ibm.com> Cc: Li Zefan <lize...@huawei.com> --- tools/perf/tests/bpf-script-test-prologue.c | 4 ++- tools/perf/util/bpf-prologue.c | 49 +++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index b4ebc75..43f1e16 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -26,9 +26,11 @@ static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = (void *) 6; SEC("func=null_lseek file->f_mode offset orig") -int bpf_func__null_lseek(void *ctx, int err, unsigned long f_mode, +int bpf_func__null_lseek(void *ctx, int err, unsigned long _f_mode, unsigned long offset, unsigned long orig) { + fmode_t f_mode = (fmode_t)_f_mode; + if (err) return 0; if (f_mode & FMODE_WRITE) diff --git a/tools/perf/util/bpf-prologue.c b/tools/perf/util/bpf-prologue.c index 6cdbee1..ce28993 100644 --- a/tools/perf/util/bpf-prologue.c +++ b/tools/perf/util/bpf-prologue.c @@ -57,6 +57,46 @@ check_pos(struct bpf_insn_pos *pos) return 0; } +/* + * Convert type string (u8/u16/u32/u64/s8/s16/s32/s64 ..., see + * Documentation/trace/kprobetrace.txt) to size field of BPF_LDX_MEM + * instruction (BPF_{B,H,W,DW}). + */ +static int +argtype_to_ldx_size(const char *type) +{ + int arg_size = type ? atoi([1]) : 64; + + switch (arg_size) { + case 8: + return BPF_B; + case 16: + return BPF_H; + case 32: + return BPF_W; + case 64: + default: + return BPF_DW; + } +} + +static const char * +insn_sz_to_str(int insn_sz) +{ + switch (insn_sz) { + case BPF_B: + return "BPF_B"; + case BPF_H: + return "BPF_H"; + case BPF_W: + return "BPF_W"; + case BPF_DW: + return "BPF_DW"; + default: + return "UNKNOWN"; + } +} + /* Give it a shorter name */ #define ins(i, p) append_insn((i), (p)) @@ -257,9 +297,14 @@ gen_prologue_slowpath(struct bpf_insn_pos *pos, } /* Final pass: read to registers */ - for (i = 0; i < nargs; i++) - ins(BPF_LDX_MEM(BPF_DW, BPF_PROLOGUE_START_ARG_REG + i, + for (i = 0; i < nargs; i++) { + int insn_sz = argtype_to_ldx_size(args[i].type); + + pr_debug("prologue: load arg %d, insn_sz is %s\n", +i, insn_sz_to_str(insn_sz)); + ins(BPF_LDX_MEM(insn_sz, BPF_PROLOGUE_START_ARG_REG + i, BPF_REG_FP, -BPF_REG_SIZE * (i + 1)), pos); + } ins(BPF_JMP_IMM(BPF_JA, BPF_REG_0, 0, JMP_TO_SUCCESS_CODE), pos); -- 2.10.1
[PATCH] perf bpf: Fix endianness problem when loading parameters in prologue
Perf BPF prologue generator unconditionally fetches 8 bytes for function parameters, which causes problem on big endian machine. Thomas gives a detail analysis for this problem: http://lkml.kernel.org/r/968ebda5-abe4-8830-8d69-49f62529d...@linux.vnet.ibm.com This patch parses the type of each argument and converts data from memory to expected type. Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Thomas Richter Cc: Alexei Starovoitov Cc: Hendrik Brueckner Cc: Li Zefan --- tools/perf/tests/bpf-script-test-prologue.c | 4 ++- tools/perf/util/bpf-prologue.c | 49 +++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index b4ebc75..43f1e16 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -26,9 +26,11 @@ static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = (void *) 6; SEC("func=null_lseek file->f_mode offset orig") -int bpf_func__null_lseek(void *ctx, int err, unsigned long f_mode, +int bpf_func__null_lseek(void *ctx, int err, unsigned long _f_mode, unsigned long offset, unsigned long orig) { + fmode_t f_mode = (fmode_t)_f_mode; + if (err) return 0; if (f_mode & FMODE_WRITE) diff --git a/tools/perf/util/bpf-prologue.c b/tools/perf/util/bpf-prologue.c index 6cdbee1..ce28993 100644 --- a/tools/perf/util/bpf-prologue.c +++ b/tools/perf/util/bpf-prologue.c @@ -57,6 +57,46 @@ check_pos(struct bpf_insn_pos *pos) return 0; } +/* + * Convert type string (u8/u16/u32/u64/s8/s16/s32/s64 ..., see + * Documentation/trace/kprobetrace.txt) to size field of BPF_LDX_MEM + * instruction (BPF_{B,H,W,DW}). + */ +static int +argtype_to_ldx_size(const char *type) +{ + int arg_size = type ? atoi([1]) : 64; + + switch (arg_size) { + case 8: + return BPF_B; + case 16: + return BPF_H; + case 32: + return BPF_W; + case 64: + default: + return BPF_DW; + } +} + +static const char * +insn_sz_to_str(int insn_sz) +{ + switch (insn_sz) { + case BPF_B: + return "BPF_B"; + case BPF_H: + return "BPF_H"; + case BPF_W: + return "BPF_W"; + case BPF_DW: + return "BPF_DW"; + default: + return "UNKNOWN"; + } +} + /* Give it a shorter name */ #define ins(i, p) append_insn((i), (p)) @@ -257,9 +297,14 @@ gen_prologue_slowpath(struct bpf_insn_pos *pos, } /* Final pass: read to registers */ - for (i = 0; i < nargs; i++) - ins(BPF_LDX_MEM(BPF_DW, BPF_PROLOGUE_START_ARG_REG + i, + for (i = 0; i < nargs; i++) { + int insn_sz = argtype_to_ldx_size(args[i].type); + + pr_debug("prologue: load arg %d, insn_sz is %s\n", +i, insn_sz_to_str(insn_sz)); + ins(BPF_LDX_MEM(insn_sz, BPF_PROLOGUE_START_ARG_REG + i, BPF_REG_FP, -BPF_REG_SIZE * (i + 1)), pos); + } ins(BPF_JMP_IMM(BPF_JA, BPF_REG_0, 0, JMP_TO_SUCCESS_CODE), pos); -- 2.10.1
[PATCH] perf test llvm: Fix f_mode endianness problem
Perf BPF prologue generator unconditionally fetches 8 bytes for function parameters. On big endian machine, a casting is resquired if the parameter is not u64. Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Arnaldo Carvalho de Melo <a...@kernel.org> Cc: Thomas Richter <tmri...@linux.vnet.ibm.com> Cc: Alexei Starovoitov <alexei.starovoi...@gmail.com> Cc: Hendrik Brueckner <brueck...@linux.vnet.ibm.com> Cc: Li Zefan <lize...@huawei.com> --- tools/perf/tests/bpf-script-test-prologue.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index b4ebc75..43f1e16 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -26,9 +26,11 @@ static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = (void *) 6; SEC("func=null_lseek file->f_mode offset orig") -int bpf_func__null_lseek(void *ctx, int err, unsigned long f_mode, +int bpf_func__null_lseek(void *ctx, int err, unsigned long _f_mode, unsigned long offset, unsigned long orig) { + fmode_t f_mode = (fmode_t)_f_mode; + if (err) return 0; if (f_mode & FMODE_WRITE) -- 2.10.1
[PATCH] perf test llvm: Fix f_mode endianness problem
Perf BPF prologue generator unconditionally fetches 8 bytes for function parameters. On big endian machine, a casting is resquired if the parameter is not u64. Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Thomas Richter Cc: Alexei Starovoitov Cc: Hendrik Brueckner Cc: Li Zefan --- tools/perf/tests/bpf-script-test-prologue.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index b4ebc75..43f1e16 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -26,9 +26,11 @@ static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = (void *) 6; SEC("func=null_lseek file->f_mode offset orig") -int bpf_func__null_lseek(void *ctx, int err, unsigned long f_mode, +int bpf_func__null_lseek(void *ctx, int err, unsigned long _f_mode, unsigned long offset, unsigned long orig) { + fmode_t f_mode = (fmode_t)_f_mode; + if (err) return 0; if (f_mode & FMODE_WRITE) -- 2.10.1
[tip:perf/core] perf test llvm: Avoid error when PROFILE_ALL_BRANCHES is set
Commit-ID: 9b57fb7e35957c6838f89f4ed7e3f8433a4bbfc5 Gitweb: http://git.kernel.org/tip/9b57fb7e35957c6838f89f4ed7e3f8433a4bbfc5 Author: Wang Nan <wangn...@huawei.com> AuthorDate: Wed, 21 Jun 2017 02:32:03 +0800 Committer: Arnaldo Carvalho de Melo <a...@redhat.com> CommitDate: Mon, 19 Jun 2017 16:11:26 -0300 perf test llvm: Avoid error when PROFILE_ALL_BRANCHES is set The 'if' keyword is a define that expands to complex code when CONFIG_PROFILE_ALL_BRANCHES is selected, which causes a 'perf test LLVM' failure like: $ ./perf test LLVM 35: LLVM search and compile: 35.1: Basic BPF llvm compile: Ok 35.2: kbuild searching : Ok 35.3: Compile source for BPF prologue generation: FAILED! 35.4: Compile source for BPF relocation : Skip The only affected test case is bpf-script-test-prologue.c because it uses kernel headers and has 'if' inside. This patch undefines 'if' to make it passes perf test. More detailed analysis from a message in this thread, also by Wang: The problem is caused by following relocation information: $ readelf -a ./llvmsubtest3 ... [ 5] _ftrace_branchPROGBITS 0260 00a0 WA 0 0 4 ... Relocation section '.relfunc=null_lseek file->f_mode offset orig' at offset 0x490 contains 4 entries: Offset Info Type Sym. ValueSym. Name 0038 000b0001 unrecognized: 1 _ftrace_branch 00b0 000b0001 unrecognized: 1 _ftrace_branch 0128 000b0001 unrecognized: 1 _ftrace_branch 01c0 000b0001 unrecognized: 1 _ftrace_branch Relocation section '.rel_ftrace_branch' at offset 0x4d0 contains 8 entries: Offset Info Type Sym. ValueSym. Name 00020001 unrecognized: 1 .L__func__.bpf_func__n 0008 00010001 unrecognized: 1 0015 .L.str 0028 00020001 unrecognized: 1 .L__func__.bpf_func__n 0030 00010001 unrecognized: 1 0015 .L.str 0050 00020001 unrecognized: 1 .L__func__.bpf_func__n 0058 00010001 unrecognized: 1 0015 .L.str 0078 00020001 unrecognized: 1 .L__func__.bpf_func__n 0080 00010001 unrecognized: 1 0015 .L.str ... So I think the failure is because you enabled CONFIG_PROFILE_ALL_BRANCHES. I can reproduce your buggy result by selecting CONFIG_PROFILE_ALL_BRANCHES in my kbuild: $ ./perf test LLVM 35: LLVM search and compile: 35.1: Basic BPF llvm compile: Ok 35.2: kbuild searching : Ok 35.3: Compile source for BPF prologue generation: FAILED! 35.4: Compile source for BPF relocation : Skip Simply undef CONFIG_PROFILE_ALL_BRANCHES in clang opts not working because it is introduced by "#include ", which override cmdline options. So I think the best way is to undefine 'if' inside BPF script. Reported-and-Tested-by: Thomas-Mich Richter <tmri...@linux.vnet.ibm.com> Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Alexei Starovoitov <alexei.starovoi...@gmail.com> Cc: Hendrik Brueckner <brueck...@linux.vnet.ibm.com> Cc: Zefan Li <lize...@huawei.com> Link: http://lkml.kernel.org/r/20170620183203.2517-1-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> --- tools/perf/tests/bpf-script-test-prologue.c | 9 + 1 file changed, 9 insertions(+) diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index 7230e62..b4ebc75 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -10,6 +10,15 @@ #include +/* + * If CONFIG_PROFILE_ALL_BRANCHES is selected, + * 'if' is redefined after include kernel header. + * Recover 'if' for BPF object code. + */ +#ifdef if +# undef if +#endif + #define FMODE_READ 0x1 #define FMODE_WRITE0x2
[tip:perf/core] perf test llvm: Avoid error when PROFILE_ALL_BRANCHES is set
Commit-ID: 9b57fb7e35957c6838f89f4ed7e3f8433a4bbfc5 Gitweb: http://git.kernel.org/tip/9b57fb7e35957c6838f89f4ed7e3f8433a4bbfc5 Author: Wang Nan AuthorDate: Wed, 21 Jun 2017 02:32:03 +0800 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 19 Jun 2017 16:11:26 -0300 perf test llvm: Avoid error when PROFILE_ALL_BRANCHES is set The 'if' keyword is a define that expands to complex code when CONFIG_PROFILE_ALL_BRANCHES is selected, which causes a 'perf test LLVM' failure like: $ ./perf test LLVM 35: LLVM search and compile: 35.1: Basic BPF llvm compile: Ok 35.2: kbuild searching : Ok 35.3: Compile source for BPF prologue generation: FAILED! 35.4: Compile source for BPF relocation : Skip The only affected test case is bpf-script-test-prologue.c because it uses kernel headers and has 'if' inside. This patch undefines 'if' to make it passes perf test. More detailed analysis from a message in this thread, also by Wang: The problem is caused by following relocation information: $ readelf -a ./llvmsubtest3 ... [ 5] _ftrace_branchPROGBITS 0260 00a0 WA 0 0 4 ... Relocation section '.relfunc=null_lseek file->f_mode offset orig' at offset 0x490 contains 4 entries: Offset Info Type Sym. ValueSym. Name 0038 000b0001 unrecognized: 1 _ftrace_branch 00b0 000b0001 unrecognized: 1 _ftrace_branch 0128 000b0001 unrecognized: 1 _ftrace_branch 01c0 000b0001 unrecognized: 1 _ftrace_branch Relocation section '.rel_ftrace_branch' at offset 0x4d0 contains 8 entries: Offset Info Type Sym. ValueSym. Name 00020001 unrecognized: 1 .L__func__.bpf_func__n 0008 00010001 unrecognized: 1 0015 .L.str 0028 00020001 unrecognized: 1 .L__func__.bpf_func__n 0030 00010001 unrecognized: 1 0015 .L.str 0050 00020001 unrecognized: 1 .L__func__.bpf_func__n 0058 00010001 unrecognized: 1 0015 .L.str 0078 00020001 unrecognized: 1 .L__func__.bpf_func__n 0080 00010001 unrecognized: 1 0015 .L.str ... So I think the failure is because you enabled CONFIG_PROFILE_ALL_BRANCHES. I can reproduce your buggy result by selecting CONFIG_PROFILE_ALL_BRANCHES in my kbuild: $ ./perf test LLVM 35: LLVM search and compile: 35.1: Basic BPF llvm compile: Ok 35.2: kbuild searching : Ok 35.3: Compile source for BPF prologue generation: FAILED! 35.4: Compile source for BPF relocation : Skip Simply undef CONFIG_PROFILE_ALL_BRANCHES in clang opts not working because it is introduced by "#include ", which override cmdline options. So I think the best way is to undefine 'if' inside BPF script. Reported-and-Tested-by: Thomas-Mich Richter Signed-off-by: Wang Nan Cc: Alexei Starovoitov Cc: Hendrik Brueckner Cc: Zefan Li Link: http://lkml.kernel.org/r/20170620183203.2517-1-wangn...@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/bpf-script-test-prologue.c | 9 + 1 file changed, 9 insertions(+) diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index 7230e62..b4ebc75 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -10,6 +10,15 @@ #include +/* + * If CONFIG_PROFILE_ALL_BRANCHES is selected, + * 'if' is redefined after include kernel header. + * Recover 'if' for BPF object code. + */ +#ifdef if +# undef if +#endif + #define FMODE_READ 0x1 #define FMODE_WRITE0x2
[PATCH] perf test llvm: Avoid error when PROFILE_ALL_BRANCHES is set
'if' is defined to complex code when CONFIG_PROFILE_ALL_BRANCHES is selected, which cause a 'perf test LLVM' failure like: $ ./perf test LLVM 35: LLVM search and compile: 35.1: Basic BPF llvm compile: Ok 35.2: kbuild searching : Ok 35.3: Compile source for BPF prologue generation: FAILED! 35.4: Compile source for BPF relocation : Skip The only affected test case is bpf-script-test-prologue.c because it uses kernel headers and has 'if' inside. This patch undefines 'if' to make it passes perf test. Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Arnaldo Carvalho de Melo <a...@redhat.com> Cc: Thomas-Mich Richter <tmri...@linux.vnet.ibm.com> Cc: Hendrik Brueckner <brueck...@linux.vnet.ibm.com> Cc: Alexei Starovoitov <alexei.starovoi...@gmail.com> Cc: Li Zefan <lize...@huawei.com> --- tools/perf/tests/bpf-script-test-prologue.c | 9 + 1 file changed, 9 insertions(+) diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index 7230e62..b4ebc75 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -10,6 +10,15 @@ #include +/* + * If CONFIG_PROFILE_ALL_BRANCHES is selected, + * 'if' is redefined after include kernel header. + * Recover 'if' for BPF object code. + */ +#ifdef if +# undef if +#endif + #define FMODE_READ 0x1 #define FMODE_WRITE0x2 -- 2.9.3
[PATCH] perf test llvm: Avoid error when PROFILE_ALL_BRANCHES is set
'if' is defined to complex code when CONFIG_PROFILE_ALL_BRANCHES is selected, which cause a 'perf test LLVM' failure like: $ ./perf test LLVM 35: LLVM search and compile: 35.1: Basic BPF llvm compile: Ok 35.2: kbuild searching : Ok 35.3: Compile source for BPF prologue generation: FAILED! 35.4: Compile source for BPF relocation : Skip The only affected test case is bpf-script-test-prologue.c because it uses kernel headers and has 'if' inside. This patch undefines 'if' to make it passes perf test. Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Thomas-Mich Richter Cc: Hendrik Brueckner Cc: Alexei Starovoitov Cc: Li Zefan --- tools/perf/tests/bpf-script-test-prologue.c | 9 + 1 file changed, 9 insertions(+) diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index 7230e62..b4ebc75 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -10,6 +10,15 @@ #include +/* + * If CONFIG_PROFILE_ALL_BRANCHES is selected, + * 'if' is redefined after include kernel header. + * Recover 'if' for BPF object code. + */ +#ifdef if +# undef if +#endif + #define FMODE_READ 0x1 #define FMODE_WRITE0x2 -- 2.9.3
[PATCH -stable 4.1 2/2] perf/core: Fix concurrent sys_perf_event_open() vs. 'move_group' race
From: Peter Zijlstra <pet...@infradead.org> [ Upstream commit 321027c1fe77f892f4ea07846aeae08cefbbb290 ] Di Shen reported a race between two concurrent sys_perf_event_open() calls where both try and move the same pre-existing software group into a hardware context. The problem is exactly that described in commit: f63a8daa5812 ("perf: Fix event->ctx locking") ... where, while we wait for a ctx->mutex acquisition, the event->ctx relation can have changed under us. That very same commit failed to recognise sys_perf_event_context() as an external access vector to the events and thereby didn't apply the established locking rules correctly. So while one sys_perf_event_open() call is stuck waiting on mutex_lock_double(), the other (which owns said locks) moves the group about. So by the time the former sys_perf_event_open() acquires the locks, the context we've acquired is stale (and possibly dead). Apply the established locking rules as per perf_event_ctx_lock_nested() to the mutex_lock_double() for the 'move_group' case. This obviously means we need to validate state after we acquire the locks. CVE-2017-6001 Reported-by: Di Shen (Keen Lab) Tested-by: John Dias <joaod...@google.com> Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org> Cc: Alexander Shishkin <alexander.shish...@linux.intel.com> Cc: Arnaldo Carvalho de Melo <a...@kernel.org> Cc: Arnaldo Carvalho de Melo <a...@redhat.com> Cc: Jiri Olsa <jo...@redhat.com> Cc: Kees Cook <keesc...@chromium.org> Cc: Linus Torvalds <torva...@linux-foundation.org> Cc: Min Chong <mch...@google.com> Cc: Peter Zijlstra <pet...@infradead.org> Cc: Stephane Eranian <eran...@google.com> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Vince Weaver <vincent.wea...@maine.edu> Fixes: f63a8daa5812 ("perf: Fix event->ctx locking") Link: http://lkml.kernel.org/r/20170106131444.gz3...@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar <mi...@kernel.org> Signed-off-by: Wang Nan <wangn...@huawei.com> [ - Correct code context - Use group_flags instead of group_caps ] --- kernel/events/core.c | 57 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 77be116..3973df8 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -7900,6 +7900,37 @@ static int perf_event_set_clock(struct perf_event *event, clockid_t clk_id) return 0; } +/* + * Variation on perf_event_ctx_lock_nested(), except we take two context + * mutexes. + */ +static struct perf_event_context * +__perf_event_ctx_lock_double(struct perf_event *group_leader, +struct perf_event_context *ctx) +{ + struct perf_event_context *gctx; + +again: + rcu_read_lock(); + gctx = READ_ONCE(group_leader->ctx); + if (!atomic_inc_not_zero(>refcount)) { + rcu_read_unlock(); + goto again; + } + rcu_read_unlock(); + + mutex_lock_double(>mutex, >mutex); + + if (group_leader->ctx != gctx) { + mutex_unlock(>mutex); + mutex_unlock(>mutex); + put_ctx(gctx); + goto again; + } + + return gctx; +} + /** * sys_perf_event_open - open a performance event, associate it to a task/cpu * @@ -8123,8 +8154,26 @@ SYSCALL_DEFINE5(perf_event_open, } if (move_group) { - gctx = group_leader->ctx; - mutex_lock_double(>mutex, >mutex); + gctx = __perf_event_ctx_lock_double(group_leader, ctx); + + /* +* Check if we raced against another sys_perf_event_open() call +* moving the software group underneath us. +*/ + if (!(group_leader->group_flags & PERF_GROUP_SOFTWARE)) { + /* +* If someone moved the group out from under us, check +* if this new event wound up on the same ctx, if so +* its the regular !move_group case, otherwise fail. +*/ + if (gctx != ctx) { + err = -EINVAL; + goto err_locked; + } else { + perf_event_ctx_unlock(group_leader, gctx); + move_group = 0; + } + } } else { mutex_lock(>mutex); } @@ -8200,7 +8249,7 @@ SYSCALL_DEFINE5(perf_event_open, perf_unpin_context(ctx); if (move_group) - mutex_unlock(>mutex); + perf_event_ctx_unlock(group_leader, gctx); mutex_unlock(>mutex); put_online_cpus(); @@ -8229,7 +82
[PATCH -stable 4.1 2/2] perf/core: Fix concurrent sys_perf_event_open() vs. 'move_group' race
From: Peter Zijlstra [ Upstream commit 321027c1fe77f892f4ea07846aeae08cefbbb290 ] Di Shen reported a race between two concurrent sys_perf_event_open() calls where both try and move the same pre-existing software group into a hardware context. The problem is exactly that described in commit: f63a8daa5812 ("perf: Fix event->ctx locking") ... where, while we wait for a ctx->mutex acquisition, the event->ctx relation can have changed under us. That very same commit failed to recognise sys_perf_event_context() as an external access vector to the events and thereby didn't apply the established locking rules correctly. So while one sys_perf_event_open() call is stuck waiting on mutex_lock_double(), the other (which owns said locks) moves the group about. So by the time the former sys_perf_event_open() acquires the locks, the context we've acquired is stale (and possibly dead). Apply the established locking rules as per perf_event_ctx_lock_nested() to the mutex_lock_double() for the 'move_group' case. This obviously means we need to validate state after we acquire the locks. CVE-2017-6001 Reported-by: Di Shen (Keen Lab) Tested-by: John Dias Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Kees Cook Cc: Linus Torvalds Cc: Min Chong Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Fixes: f63a8daa5812 ("perf: Fix event->ctx locking") Link: http://lkml.kernel.org/r/20170106131444.gz3...@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar Signed-off-by: Wang Nan [ - Correct code context - Use group_flags instead of group_caps ] --- kernel/events/core.c | 57 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 77be116..3973df8 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -7900,6 +7900,37 @@ static int perf_event_set_clock(struct perf_event *event, clockid_t clk_id) return 0; } +/* + * Variation on perf_event_ctx_lock_nested(), except we take two context + * mutexes. + */ +static struct perf_event_context * +__perf_event_ctx_lock_double(struct perf_event *group_leader, +struct perf_event_context *ctx) +{ + struct perf_event_context *gctx; + +again: + rcu_read_lock(); + gctx = READ_ONCE(group_leader->ctx); + if (!atomic_inc_not_zero(>refcount)) { + rcu_read_unlock(); + goto again; + } + rcu_read_unlock(); + + mutex_lock_double(>mutex, >mutex); + + if (group_leader->ctx != gctx) { + mutex_unlock(>mutex); + mutex_unlock(>mutex); + put_ctx(gctx); + goto again; + } + + return gctx; +} + /** * sys_perf_event_open - open a performance event, associate it to a task/cpu * @@ -8123,8 +8154,26 @@ SYSCALL_DEFINE5(perf_event_open, } if (move_group) { - gctx = group_leader->ctx; - mutex_lock_double(>mutex, >mutex); + gctx = __perf_event_ctx_lock_double(group_leader, ctx); + + /* +* Check if we raced against another sys_perf_event_open() call +* moving the software group underneath us. +*/ + if (!(group_leader->group_flags & PERF_GROUP_SOFTWARE)) { + /* +* If someone moved the group out from under us, check +* if this new event wound up on the same ctx, if so +* its the regular !move_group case, otherwise fail. +*/ + if (gctx != ctx) { + err = -EINVAL; + goto err_locked; + } else { + perf_event_ctx_unlock(group_leader, gctx); + move_group = 0; + } + } } else { mutex_lock(>mutex); } @@ -8200,7 +8249,7 @@ SYSCALL_DEFINE5(perf_event_open, perf_unpin_context(ctx); if (move_group) - mutex_unlock(>mutex); + perf_event_ctx_unlock(group_leader, gctx); mutex_unlock(>mutex); put_online_cpus(); @@ -8229,7 +8278,7 @@ SYSCALL_DEFINE5(perf_event_open, err_locked: if (move_group) - mutex_unlock(>mutex); + perf_event_ctx_unlock(group_leader, gctx); mutex_unlock(>mutex); /* err_file: */ fput(event_file); -- 2.10.1
[PATCH -stable 4.1 1/2] perf: Restructure perf syscall point of no return
From: Peter Zijlstra <pet...@infradead.org> [ Upstream commit f55fc2a57cc9ca3b1bb4fb8eb25b6e1989e5b993 ] The exclusive_event_installable() stuff only works because its exclusive with the grouping bits. Rework the code such that there is a sane place to error out before we go do things we cannot undo. CVE 2017-6001 Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org> Cc: Alexander Shishkin <alexander.shish...@linux.intel.com> Cc: Linus Torvalds <torva...@linux-foundation.org> Cc: Peter Zijlstra <pet...@infradead.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar <mi...@kernel.org> Signed-off-by: Wang Nan <wangn...@huawei.com> --- kernel/events/core.c | 49 - 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 6da64f0..77be116 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -8124,13 +8124,30 @@ SYSCALL_DEFINE5(perf_event_open, if (move_group) { gctx = group_leader->ctx; + mutex_lock_double(>mutex, >mutex); + } else { + mutex_lock(>mutex); + } + + /* +* Must be under the same ctx::mutex as perf_install_in_context(), +* because we need to serialize with concurrent event creation. +*/ + if (!exclusive_event_installable(event, ctx)) { + /* exclusive and group stuff are assumed mutually exclusive */ + WARN_ON_ONCE(move_group); + + err = -EBUSY; + goto err_locked; + } + WARN_ON_ONCE(ctx->parent_ctx); + + if (move_group) { /* * See perf_event_ctx_lock() for comments on the details * of swizzling perf_event::ctx. */ - mutex_lock_double(>mutex, >mutex); - perf_remove_from_context(group_leader, false); list_for_each_entry(sibling, _leader->sibling_list, @@ -8138,13 +8155,7 @@ SYSCALL_DEFINE5(perf_event_open, perf_remove_from_context(sibling, false); put_ctx(gctx); } - } else { - mutex_lock(>mutex); - } - - WARN_ON_ONCE(ctx->parent_ctx); - if (move_group) { /* * Wait for everybody to stop referencing the events through * the old lists, before installing it on new lists. @@ -8176,22 +8187,20 @@ SYSCALL_DEFINE5(perf_event_open, perf_event__state_init(group_leader); perf_install_in_context(ctx, group_leader, group_leader->cpu); get_ctx(ctx); - } - if (!exclusive_event_installable(event, ctx)) { - err = -EBUSY; - mutex_unlock(>mutex); - fput(event_file); - goto err_context; + /* +* Now that all events are installed in @ctx, nothing +* references @gctx anymore, so drop the last reference we have +* on it. +*/ + put_ctx(gctx); } perf_install_in_context(ctx, event, event->cpu); perf_unpin_context(ctx); - if (move_group) { + if (move_group) mutex_unlock(>mutex); - put_ctx(gctx); - } mutex_unlock(>mutex); put_online_cpus(); @@ -8218,6 +8227,12 @@ SYSCALL_DEFINE5(perf_event_open, fd_install(event_fd, event_file); return event_fd; +err_locked: + if (move_group) + mutex_unlock(>mutex); + mutex_unlock(>mutex); +/* err_file: */ + fput(event_file); err_context: perf_unpin_context(ctx); put_ctx(ctx); -- 2.10.1
[PATCH -stable 4.1 0/2] perf/core: Fix CVE-2017-6001
These two patch are needed for stable 4.1. They fix CVE-2017-6001. Peter Zijlstra (2): perf: Restructure perf syscall point of no return perf/core: Fix concurrent sys_perf_event_open() vs. 'move_group' race kernel/events/core.c | 102 +-- 1 file changed, 83 insertions(+), 19 deletions(-) -- 2.10.1