diff options
Diffstat (limited to 'kernel/tools/perf/util')
-rw-r--r-- | kernel/tools/perf/util/event.c | 2 | ||||
-rw-r--r-- | kernel/tools/perf/util/evlist.c | 4 | ||||
-rw-r--r-- | kernel/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 38 | ||||
-rw-r--r-- | kernel/tools/perf/util/intel-pt.c | 17 | ||||
-rw-r--r-- | kernel/tools/perf/util/parse-events.c | 6 | ||||
-rw-r--r-- | kernel/tools/perf/util/pmu.c | 15 | ||||
-rw-r--r-- | kernel/tools/perf/util/setup.py | 4 | ||||
-rw-r--r-- | kernel/tools/perf/util/stat.c | 10 | ||||
-rw-r--r-- | kernel/tools/perf/util/symbol-elf.c | 3 | ||||
-rw-r--r-- | kernel/tools/perf/util/symbol.c | 5 | ||||
-rw-r--r-- | kernel/tools/perf/util/trace-event-scripting.c | 6 |
11 files changed, 87 insertions, 23 deletions
diff --git a/kernel/tools/perf/util/event.c b/kernel/tools/perf/util/event.c index 8b10621b4..956187bf1 100644 --- a/kernel/tools/perf/util/event.c +++ b/kernel/tools/perf/util/event.c @@ -274,7 +274,7 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, strcpy(execname, ""); /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ - n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %s\n", + n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %[^\n]\n", &event->mmap2.start, &event->mmap2.len, prot, &event->mmap2.pgoff, &event->mmap2.maj, &event->mmap2.min, diff --git a/kernel/tools/perf/util/evlist.c b/kernel/tools/perf/util/evlist.c index d1392194a..b4b96120f 100644 --- a/kernel/tools/perf/util/evlist.c +++ b/kernel/tools/perf/util/evlist.c @@ -1211,12 +1211,12 @@ void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, */ if (cpus != evlist->cpus) { cpu_map__put(evlist->cpus); - evlist->cpus = cpus; + evlist->cpus = cpu_map__get(cpus); } if (threads != evlist->threads) { thread_map__put(evlist->threads); - evlist->threads = threads; + evlist->threads = thread_map__get(threads); } perf_evlist__propagate_maps(evlist); diff --git a/kernel/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/kernel/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c index 9409d014b..71df7acf8 100644 --- a/kernel/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +++ b/kernel/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c @@ -89,6 +89,7 @@ struct intel_pt_decoder { bool pge; bool have_tma; bool have_cyc; + bool fixup_last_mtc; uint64_t pos; uint64_t last_ip; uint64_t ip; @@ -584,10 +585,31 @@ struct intel_pt_calc_cyc_to_tsc_info { uint64_t tsc_timestamp; uint64_t timestamp; bool have_tma; + bool fixup_last_mtc; bool from_mtc; double cbr_cyc_to_tsc; }; +/* + * MTC provides a 8-bit slice of CTC but the TMA packet only provides the lower + * 16 bits of CTC. If mtc_shift > 8 then some of the MTC bits are not in the CTC + * provided by the TMA packet. Fix-up the last_mtc calculated from the TMA + * packet by copying the missing bits from the current MTC assuming the least + * difference between the two, and that the current MTC comes after last_mtc. + */ +static void intel_pt_fixup_last_mtc(uint32_t mtc, int mtc_shift, + uint32_t *last_mtc) +{ + uint32_t first_missing_bit = 1U << (16 - mtc_shift); + uint32_t mask = ~(first_missing_bit - 1); + + *last_mtc |= mtc & mask; + if (*last_mtc >= mtc) { + *last_mtc -= first_missing_bit; + *last_mtc &= 0xff; + } +} + static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info) { struct intel_pt_decoder *decoder = pkt_info->decoder; @@ -617,6 +639,11 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info) return 0; mtc = pkt_info->packet.payload; + if (decoder->mtc_shift > 8 && data->fixup_last_mtc) { + data->fixup_last_mtc = false; + intel_pt_fixup_last_mtc(mtc, decoder->mtc_shift, + &data->last_mtc); + } if (mtc > data->last_mtc) mtc_delta = mtc - data->last_mtc; else @@ -685,6 +712,7 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info) data->ctc_delta = 0; data->have_tma = true; + data->fixup_last_mtc = true; return 0; @@ -751,6 +779,7 @@ static void intel_pt_calc_cyc_to_tsc(struct intel_pt_decoder *decoder, .tsc_timestamp = decoder->tsc_timestamp, .timestamp = decoder->timestamp, .have_tma = decoder->have_tma, + .fixup_last_mtc = decoder->fixup_last_mtc, .from_mtc = from_mtc, .cbr_cyc_to_tsc = 0, }; @@ -1241,6 +1270,7 @@ static void intel_pt_calc_tma(struct intel_pt_decoder *decoder) } decoder->ctc_delta = 0; decoder->have_tma = true; + decoder->fixup_last_mtc = true; intel_pt_log("CTC timestamp " x64_fmt " last MTC %#x CTC rem %#x\n", decoder->ctc_timestamp, decoder->last_mtc, ctc_rem); } @@ -1255,6 +1285,12 @@ static void intel_pt_calc_mtc_timestamp(struct intel_pt_decoder *decoder) mtc = decoder->packet.payload; + if (decoder->mtc_shift > 8 && decoder->fixup_last_mtc) { + decoder->fixup_last_mtc = false; + intel_pt_fixup_last_mtc(mtc, decoder->mtc_shift, + &decoder->last_mtc); + } + if (mtc > decoder->last_mtc) mtc_delta = mtc - decoder->last_mtc; else @@ -1323,6 +1359,8 @@ static void intel_pt_calc_cyc_timestamp(struct intel_pt_decoder *decoder) timestamp, decoder->timestamp); else decoder->timestamp = timestamp; + + decoder->timestamp_insn_cnt = 0; } /* Walk PSB+ packets when already in sync. */ diff --git a/kernel/tools/perf/util/intel-pt.c b/kernel/tools/perf/util/intel-pt.c index 97f963a3d..89927b5be 100644 --- a/kernel/tools/perf/util/intel-pt.c +++ b/kernel/tools/perf/util/intel-pt.c @@ -238,7 +238,7 @@ static int intel_pt_get_trace(struct intel_pt_buffer *b, void *data) } queue = &ptq->pt->queues.queue_array[ptq->queue_nr]; - +next: buffer = auxtrace_buffer__next(queue, buffer); if (!buffer) { if (old_buffer) @@ -261,9 +261,6 @@ static int intel_pt_get_trace(struct intel_pt_buffer *b, void *data) intel_pt_do_fix_overlap(ptq->pt, old_buffer, buffer)) return -ENOMEM; - if (old_buffer) - auxtrace_buffer__drop_data(old_buffer); - if (buffer->use_data) { b->len = buffer->use_size; b->buf = buffer->use_data; @@ -273,6 +270,16 @@ static int intel_pt_get_trace(struct intel_pt_buffer *b, void *data) } b->ref_timestamp = buffer->reference; + /* + * If in snapshot mode and the buffer has no usable data, get next + * buffer and again check overlap against old_buffer. + */ + if (ptq->pt->snapshot_mode && !b->len) + goto next; + + if (old_buffer) + auxtrace_buffer__drop_data(old_buffer); + if (!old_buffer || ptq->pt->sampling_mode || (ptq->pt->snapshot_mode && !buffer->consecutive)) { b->consecutive = false; @@ -1127,7 +1134,7 @@ static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq) pr_err("Intel Processor Trace: failed to deliver transaction event, error %d\n", ret); - if (pt->synth_opts.callchain) + if (pt->synth_opts.last_branch) intel_pt_reset_last_branch_rb(ptq); return ret; diff --git a/kernel/tools/perf/util/parse-events.c b/kernel/tools/perf/util/parse-events.c index b48e87693..a35db828b 100644 --- a/kernel/tools/perf/util/parse-events.c +++ b/kernel/tools/perf/util/parse-events.c @@ -2101,11 +2101,11 @@ char *parse_events_formats_error_string(char *additional_terms) /* valid terms */ if (additional_terms) { - if (!asprintf(&str, "valid terms: %s,%s", - additional_terms, static_terms)) + if (asprintf(&str, "valid terms: %s,%s", + additional_terms, static_terms) < 0) goto fail; } else { - if (!asprintf(&str, "valid terms: %s", static_terms)) + if (asprintf(&str, "valid terms: %s", static_terms) < 0) goto fail; } return str; diff --git a/kernel/tools/perf/util/pmu.c b/kernel/tools/perf/util/pmu.c index e4b173dec..6f2a02794 100644 --- a/kernel/tools/perf/util/pmu.c +++ b/kernel/tools/perf/util/pmu.c @@ -283,13 +283,12 @@ static int pmu_aliases_parse(char *dir, struct list_head *head) { struct dirent *evt_ent; DIR *event_dir; - int ret = 0; event_dir = opendir(dir); if (!event_dir) return -EINVAL; - while (!ret && (evt_ent = readdir(event_dir))) { + while ((evt_ent = readdir(event_dir))) { char path[PATH_MAX]; char *name = evt_ent->d_name; FILE *file; @@ -305,17 +304,19 @@ static int pmu_aliases_parse(char *dir, struct list_head *head) snprintf(path, PATH_MAX, "%s/%s", dir, name); - ret = -EINVAL; file = fopen(path, "r"); - if (!file) - break; + if (!file) { + pr_debug("Cannot open %s\n", path); + continue; + } - ret = perf_pmu__new_alias(head, dir, name, file); + if (perf_pmu__new_alias(head, dir, name, file) < 0) + pr_debug("Cannot set up %s\n", name); fclose(file); } closedir(event_dir); - return ret; + return 0; } /* diff --git a/kernel/tools/perf/util/setup.py b/kernel/tools/perf/util/setup.py index 183310376..c8680984d 100644 --- a/kernel/tools/perf/util/setup.py +++ b/kernel/tools/perf/util/setup.py @@ -22,6 +22,7 @@ cflags = getenv('CFLAGS', '').split() # switch off several checks (need to be at the end of cflags list) cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ] +src_perf = getenv('srctree') + '/tools/perf' build_lib = getenv('PYTHON_EXTBUILD_LIB') build_tmp = getenv('PYTHON_EXTBUILD_TMP') libtraceevent = getenv('LIBTRACEEVENT') @@ -30,6 +31,9 @@ libapikfs = getenv('LIBAPI') ext_sources = [f.strip() for f in file('util/python-ext-sources') if len(f.strip()) > 0 and f[0] != '#'] +# use full paths with source files +ext_sources = map(lambda x: '%s/%s' % (src_perf, x) , ext_sources) + perf = Extension('perf', sources = ext_sources, include_dirs = ['util/include'], diff --git a/kernel/tools/perf/util/stat.c b/kernel/tools/perf/util/stat.c index 4a3a72cb5..6ce624cb7 100644 --- a/kernel/tools/perf/util/stat.c +++ b/kernel/tools/perf/util/stat.c @@ -311,6 +311,16 @@ int perf_stat_process_counter(struct perf_stat_config *config, aggr->val = aggr->ena = aggr->run = 0; + /* + * We calculate counter's data every interval, + * and the display code shows ps->res_stats + * avg value. We need to zero the stats for + * interval mode, otherwise overall avg running + * averages will be shown for each interval. + */ + if (config->interval) + init_stats(ps->res_stats); + if (counter->per_pkg) zero_per_pkg(counter); diff --git a/kernel/tools/perf/util/symbol-elf.c b/kernel/tools/perf/util/symbol-elf.c index 475d88d0a..27ae382fe 100644 --- a/kernel/tools/perf/util/symbol-elf.c +++ b/kernel/tools/perf/util/symbol-elf.c @@ -1091,9 +1091,8 @@ new_symbol: * For misannotated, zeroed, ASM function sizes. */ if (nr > 0) { - if (!symbol_conf.allow_aliases) - symbols__fixup_duplicate(&dso->symbols[map->type]); symbols__fixup_end(&dso->symbols[map->type]); + symbols__fixup_duplicate(&dso->symbols[map->type]); if (kmap) { /* * We need to fixup this here too because we create new diff --git a/kernel/tools/perf/util/symbol.c b/kernel/tools/perf/util/symbol.c index cd08027a6..520a32a12 100644 --- a/kernel/tools/perf/util/symbol.c +++ b/kernel/tools/perf/util/symbol.c @@ -151,6 +151,9 @@ void symbols__fixup_duplicate(struct rb_root *symbols) struct rb_node *nd; struct symbol *curr, *next; + if (symbol_conf.allow_aliases) + return; + nd = rb_first(symbols); while (nd) { @@ -1275,8 +1278,8 @@ int dso__load_kallsyms(struct dso *dso, const char *filename, if (kallsyms__delta(map, filename, &delta)) return -1; - symbols__fixup_duplicate(&dso->symbols[map->type]); symbols__fixup_end(&dso->symbols[map->type]); + symbols__fixup_duplicate(&dso->symbols[map->type]); if (dso->kernel == DSO_TYPE_GUEST_KERNEL) dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS; diff --git a/kernel/tools/perf/util/trace-event-scripting.c b/kernel/tools/perf/util/trace-event-scripting.c index 9df61059a..a2fd6e79d 100644 --- a/kernel/tools/perf/util/trace-event-scripting.c +++ b/kernel/tools/perf/util/trace-event-scripting.c @@ -95,7 +95,8 @@ static void register_python_scripting(struct scripting_ops *scripting_ops) if (err) die("error registering py script extension"); - scripting_context = malloc(sizeof(struct scripting_context)); + if (scripting_context == NULL) + scripting_context = malloc(sizeof(*scripting_context)); } #ifdef NO_LIBPYTHON @@ -159,7 +160,8 @@ static void register_perl_scripting(struct scripting_ops *scripting_ops) if (err) die("error registering pl script extension"); - scripting_context = malloc(sizeof(struct scripting_context)); + if (scripting_context == NULL) + scripting_context = malloc(sizeof(*scripting_context)); } #ifdef NO_LIBPERL |