aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorKan Liang <kan.liang@intel.com>2018-01-18 16:26:31 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2018-02-15 07:56:54 -0500
commitebebbf082357f86cc84a4d46ce897a5750e41b7a (patch)
tree813fd6783ba8071a9978d5296dfa5982927619ce /tools/perf
parenta1ff5b05e988ca3620027148cd61013408ea4194 (diff)
perf top: Switch default mode to overwrite mode
perf_top__mmap_read() has a severe performance issue in the Knights Landing/Mill platform, when monitoring heavy load systems. It costs several minutes to finish, which is unacceptable. Currently, 'perf top' uses the non overwrite mode. For non overwrite mode, it tries to read everything in the ringbuffer and doesn't pause it. Once there are lots of samples delivered persistently, the processing time could be very long. Also, the latest samples could be lost when the ringbuffer is full. For overwrite mode, it takes a snapshot for the system by pausing the ringbuffer, which could significantly reduce the processing time. Also, the overwrite mode always keep the latest samples. Considering the real time requirement for 'perf top', the overwrite mode is more suitable for it. Actually, 'perf top' was overwrite mode. It is changed to non overwrite mode since commit 93fc64f14472 ("perf top: Switch to non overwrite mode"). It's better to change it back to overwrite mode by default. For the kernel which doesn't support overwrite mode, it will fall back to non overwrite mode. There would be some records lost in overwrite mode because of pausing the ringbuffer. It has little impact for the accuracy of the snapshot and can be tolerated. For overwrite mode, unconditionally wait 100 ms before each snapshot. It also reduces the overhead caused by pausing ringbuffer, especially on light load system. Signed-off-by: Kan Liang <kan.liang@intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Jin Yao <yao.jin@linux.intel.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/r/1516310792-208685-17-git-send-email-kan.liang@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-top.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 59653062bb48..2b4914f34ed6 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -809,15 +809,23 @@ static void perf_event__process_sample(struct perf_tool *tool,
809 809
810static void perf_top__mmap_read_idx(struct perf_top *top, int idx) 810static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
811{ 811{
812 struct record_opts *opts = &top->record_opts;
813 struct perf_evlist *evlist = top->evlist;
812 struct perf_sample sample; 814 struct perf_sample sample;
813 struct perf_evsel *evsel; 815 struct perf_evsel *evsel;
816 struct perf_mmap *md;
814 struct perf_session *session = top->session; 817 struct perf_session *session = top->session;
815 union perf_event *event; 818 union perf_event *event;
816 struct machine *machine; 819 struct machine *machine;
820 u64 end, start;
817 int ret; 821 int ret;
818 822
819 while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) { 823 md = opts->overwrite ? &evlist->overwrite_mmap[idx] : &evlist->mmap[idx];
820 ret = perf_evlist__parse_sample(top->evlist, event, &sample); 824 if (perf_mmap__read_init(md, opts->overwrite, &start, &end) < 0)
825 return;
826
827 while ((event = perf_mmap__read_event(md, opts->overwrite, &start, end)) != NULL) {
828 ret = perf_evlist__parse_sample(evlist, event, &sample);
821 if (ret) { 829 if (ret) {
822 pr_err("Can't parse sample, err = %d\n", ret); 830 pr_err("Can't parse sample, err = %d\n", ret);
823 goto next_event; 831 goto next_event;
@@ -871,16 +879,28 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
871 } else 879 } else
872 ++session->evlist->stats.nr_unknown_events; 880 ++session->evlist->stats.nr_unknown_events;
873next_event: 881next_event:
874 perf_evlist__mmap_consume(top->evlist, idx); 882 perf_mmap__consume(md, opts->overwrite);
875 } 883 }
884
885 perf_mmap__read_done(md);
876} 886}
877 887
878static void perf_top__mmap_read(struct perf_top *top) 888static void perf_top__mmap_read(struct perf_top *top)
879{ 889{
890 bool overwrite = top->record_opts.overwrite;
891 struct perf_evlist *evlist = top->evlist;
880 int i; 892 int i;
881 893
894 if (overwrite)
895 perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_DATA_PENDING);
896
882 for (i = 0; i < top->evlist->nr_mmaps; i++) 897 for (i = 0; i < top->evlist->nr_mmaps; i++)
883 perf_top__mmap_read_idx(top, i); 898 perf_top__mmap_read_idx(top, i);
899
900 if (overwrite) {
901 perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY);
902 perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING);
903 }
884} 904}
885 905
886/* 906/*
@@ -979,11 +999,6 @@ static int perf_top__start_counters(struct perf_top *top)
979 goto out_err; 999 goto out_err;
980 } 1000 }
981 1001
982 if (opts->overwrite) {
983 ui__error("not support overwrite mode yet\n");
984 goto out_err;
985 }
986
987 perf_evlist__config(evlist, opts, &callchain_param); 1002 perf_evlist__config(evlist, opts, &callchain_param);
988 1003
989 evlist__for_each_entry(evlist, counter) { 1004 evlist__for_each_entry(evlist, counter) {
@@ -1144,7 +1159,7 @@ static int __cmd_top(struct perf_top *top)
1144 1159
1145 perf_top__mmap_read(top); 1160 perf_top__mmap_read(top);
1146 1161
1147 if (hits == top->samples) 1162 if (opts->overwrite || (hits == top->samples))
1148 ret = perf_evlist__poll(top->evlist, 100); 1163 ret = perf_evlist__poll(top->evlist, 100);
1149 1164
1150 if (resize) { 1165 if (resize) {
@@ -1238,6 +1253,7 @@ int cmd_top(int argc, const char **argv)
1238 .uses_mmap = true, 1253 .uses_mmap = true,
1239 }, 1254 },
1240 .proc_map_timeout = 500, 1255 .proc_map_timeout = 500,
1256 .overwrite = 1,
1241 }, 1257 },
1242 .max_stack = sysctl_perf_event_max_stack, 1258 .max_stack = sysctl_perf_event_max_stack,
1243 .sym_pcnt_filter = 5, 1259 .sym_pcnt_filter = 5,