diff options
author | Ingo Molnar | 2019-07-23 23:41:33 +0200 |
---|---|---|
committer | Ingo Molnar | 2019-07-23 23:41:33 +0200 |
commit | 49902052fc6b9babf5b60fb5e31b821299f3f675 (patch) | |
tree | d1c091f55f7f5f479d69a89f7e7909e2b627c0b6 /tools/perf | |
parent | 7b5cf701ea9c395c792e2a7e3b7caf4c68b87721 (diff) | |
parent | 39e7317e37f7f0be366d1201c283f968c17268da (diff) |
Merge tag 'perf-urgent-for-mingo-5.3-20190723' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/urgent fixes from Arnaldo Carvalho de Melo:
perf.data:
Alexey Budankov:
- Fix loading of compressed data split across adjacent records
Jiri Olsa:
- Fix buffer size setting for processing CPU topology perf.data header.
perf stat:
Jiri Olsa:
- Fix segfault for event group in repeat mode
Cong Wang:
- Always separate "stalled cycles per insn" line, it was being appended to
the "instructions" line.
perf script:
Andi Kleen:
- Fix --max-blocks man page description.
- Improve man page description of metrics.
- Fix off by one in brstackinsn IPC computation.
perf probe:
Arnaldo Carvalho de Melo:
- Avoid calling freeing routine multiple times for same pointer.
perf build:
- Do not use -Wshadow on gcc < 4.8, avoiding too strict warnings
treated as errors, breaking the build.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/Documentation/perf-script.txt | 8 | ||||
-rw-r--r-- | tools/perf/builtin-probe.c | 10 | ||||
-rw-r--r-- | tools/perf/builtin-script.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 9 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 2 | ||||
-rw-r--r-- | tools/perf/util/header.c | 2 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 1 | ||||
-rw-r--r-- | tools/perf/util/session.c | 22 | ||||
-rw-r--r-- | tools/perf/util/session.h | 1 | ||||
-rw-r--r-- | tools/perf/util/stat-shadow.c | 3 | ||||
-rw-r--r-- | tools/perf/util/zstd.c | 4 |
11 files changed, 46 insertions, 18 deletions
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index d4e2e18a5881..caaab28f8400 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -228,11 +228,11 @@ OPTIONS With the metric option perf script can compute metrics for sampling periods, similar to perf stat. This requires - specifying a group with multiple metrics with the :S option + specifying a group with multiple events defining metrics with the :S option for perf record. perf will sample on the first event, and - compute metrics for all the events in the group. Please note + print computed metrics for all the events in the group. Please note that the metric computed is averaged over the whole sampling - period, not just for the sample point. + period (since the last sample), not just for the sample point. For sample events it's possible to display misc field with -F +misc option, following letters are displayed for each bit: @@ -384,7 +384,7 @@ include::itrace.txt[] perf script --time 0%-10%,30%-40% --max-blocks:: - Set the maximum number of program blocks to print with brstackasm for + Set the maximum number of program blocks to print with brstackinsn for each sample. --reltime:: diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 6418782951a4..3d0ffd41fb55 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -698,6 +698,16 @@ __cmd_probe(int argc, const char **argv) ret = perf_add_probe_events(params.events, params.nevents); if (ret < 0) { + + /* + * When perf_add_probe_events() fails it calls + * cleanup_perf_probe_events(pevs, npevs), i.e. + * cleanup_perf_probe_events(params.events, params.nevents), which + * will call clear_perf_probe_event(), so set nevents to zero + * to avoid cleanup_params() to call clear_perf_probe_event() again + * on the same pevs. + */ + params.nevents = 0; pr_err_with_code(" Error: Failed to add events.", ret); return ret; } diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 8f24865596af..0140ddb8dd0b 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1059,7 +1059,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp); if (ip == end) { - printed += ip__fprintf_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn, fp, + printed += ip__fprintf_jump(ip, &br->entries[i], &x, buffer + off, len - off, ++insn, fp, &total_cycles); if (PRINT_FIELD(SRCCODE)) printed += print_srccode(thread, x.cpumode, ip); diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index b55a534b4de0..352cf39d7c2f 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -607,7 +607,13 @@ try_again: * group leaders. */ read_counters(&(struct timespec) { .tv_nsec = t1-t0 }); - perf_evlist__close(evsel_list); + + /* + * We need to keep evsel_list alive, because it's processed + * later the evsel_list will be closed after. + */ + if (!STAT_RECORD) + perf_evlist__close(evsel_list); return WEXITSTATUS(status); } @@ -1997,6 +2003,7 @@ int cmd_stat(int argc, const char **argv) perf_session__write_header(perf_stat.session, evsel_list, fd, true); } + perf_evlist__close(evsel_list); perf_session__delete(perf_stat.session); } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ebb46da4dfe5..52459dd5ad0c 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1291,6 +1291,7 @@ static void perf_evsel__free_id(struct perf_evsel *evsel) xyarray__delete(evsel->sample_id); evsel->sample_id = NULL; zfree(&evsel->id); + evsel->ids = 0; } static void perf_evsel__free_config_terms(struct perf_evsel *evsel) @@ -2077,6 +2078,7 @@ void perf_evsel__close(struct perf_evsel *evsel) perf_evsel__close_fd(evsel); perf_evsel__free_fd(evsel); + perf_evsel__free_id(evsel); } int perf_evsel__open_per_cpu(struct perf_evsel *evsel, diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index c24db7f4909c..20111f8da5cb 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -3747,7 +3747,7 @@ int perf_event__process_feature(struct perf_session *session, return 0; ff.buf = (void *)fe->data; - ff.size = event->header.size - sizeof(event->header); + ff.size = event->header.size - sizeof(*fe); ff.ph = &session->header; if (feat_ops[feat].process(&ff, NULL)) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index cd1eb73cfe83..8394d48f8b32 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2230,6 +2230,7 @@ void clear_perf_probe_event(struct perf_probe_event *pev) field = next; } } + pev->nargs = 0; zfree(&pev->args); } diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index d0fd6c614e68..37efa1f43d8b 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -36,10 +36,16 @@ static int perf_session__process_compressed_event(struct perf_session *session, void *src; size_t decomp_size, src_size; u64 decomp_last_rem = 0; - size_t decomp_len = session->header.env.comp_mmap_len; + size_t mmap_len, decomp_len = session->header.env.comp_mmap_len; struct decomp *decomp, *decomp_last = session->decomp_last; - decomp = mmap(NULL, sizeof(struct decomp) + decomp_len, PROT_READ|PROT_WRITE, + if (decomp_last) { + decomp_last_rem = decomp_last->size - decomp_last->head; + decomp_len += decomp_last_rem; + } + + mmap_len = sizeof(struct decomp) + decomp_len; + decomp = mmap(NULL, mmap_len, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); if (decomp == MAP_FAILED) { pr_err("Couldn't allocate memory for decompression\n"); @@ -47,10 +53,10 @@ static int perf_session__process_compressed_event(struct perf_session *session, } decomp->file_pos = file_offset; + decomp->mmap_len = mmap_len; decomp->head = 0; - if (decomp_last) { - decomp_last_rem = decomp_last->size - decomp_last->head; + if (decomp_last_rem) { memcpy(decomp->data, &(decomp_last->data[decomp_last->head]), decomp_last_rem); decomp->size = decomp_last_rem; } @@ -61,7 +67,7 @@ static int perf_session__process_compressed_event(struct perf_session *session, decomp_size = zstd_decompress_stream(&(session->zstd_data), src, src_size, &(decomp->data[decomp_last_rem]), decomp_len - decomp_last_rem); if (!decomp_size) { - munmap(decomp, sizeof(struct decomp) + decomp_len); + munmap(decomp, mmap_len); pr_err("Couldn't decompress data\n"); return -1; } @@ -255,15 +261,15 @@ static void perf_session__delete_threads(struct perf_session *session) static void perf_session__release_decomp_events(struct perf_session *session) { struct decomp *next, *decomp; - size_t decomp_len; + size_t mmap_len; next = session->decomp; - decomp_len = session->header.env.comp_mmap_len; do { decomp = next; if (decomp == NULL) break; next = decomp->next; - munmap(decomp, decomp_len + sizeof(struct decomp)); + mmap_len = decomp->mmap_len; + munmap(decomp, mmap_len); } while (1); } diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index dd8920b745bc..863dbad87849 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -46,6 +46,7 @@ struct perf_session { struct decomp { struct decomp *next; u64 file_pos; + size_t mmap_len; u64 head; size_t size; char data[]; diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 656065af4971..accb1bf1cfd8 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -819,7 +819,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, "stalled cycles per insn", ratio); } else if (have_frontend_stalled) { - print_metric(config, ctxp, NULL, NULL, + out->new_line(config, ctxp); + print_metric(config, ctxp, NULL, "%7.2f ", "stalled cycles per insn", 0); } } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES)) { diff --git a/tools/perf/util/zstd.c b/tools/perf/util/zstd.c index 23bdb9884576..d2202392ffdb 100644 --- a/tools/perf/util/zstd.c +++ b/tools/perf/util/zstd.c @@ -99,8 +99,8 @@ size_t zstd_decompress_stream(struct zstd_data *data, void *src, size_t src_size while (input.pos < input.size) { ret = ZSTD_decompressStream(data->dstream, &output, &input); if (ZSTD_isError(ret)) { - pr_err("failed to decompress (B): %ld -> %ld : %s\n", - src_size, output.size, ZSTD_getErrorName(ret)); + pr_err("failed to decompress (B): %ld -> %ld, dst_size %ld : %s\n", + src_size, output.size, dst_size, ZSTD_getErrorName(ret)); break; } output.dst = dst + output.pos; |