summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/perf/Documentation/perf-list.txt2
-rw-r--r--tools/perf/Documentation/perf-stat.txt5
-rw-r--r--tools/perf/builtin-list.c18
-rw-r--r--tools/perf/builtin-probe.c8
-rw-r--r--tools/perf/builtin-record.c16
-rw-r--r--tools/perf/builtin-stat.c13
-rw-r--r--tools/perf/builtin-top.c10
-rw-r--r--tools/perf/util/hist.c2
-rw-r--r--tools/perf/util/machine.c2
-rw-r--r--tools/perf/util/pmu.c3
-rw-r--r--tools/perf/util/probe-event.c8
-rw-r--r--tools/perf/util/session.c2
-rw-r--r--tools/perf/util/session.h2
13 files changed, 65 insertions, 26 deletions
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index bada8933fdd4..ad60c6ea1997 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -125,6 +125,8 @@ To limit the list use:
. If none of the above is matched, it will apply the supplied glob to all
events, printing the ones that match.
+. As a last resort, it will do a substring search in all event names.
+
One or more types can be used at the same time, listing the events for the
types specified.
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 47469abdcc1c..4e074a660826 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -128,8 +128,9 @@ perf stat --repeat 10 --null --sync --pre 'make -s O=defconfig-build/clean' -- m
-I msecs::
--interval-print msecs::
- Print count deltas every N milliseconds (minimum: 100ms)
- example: perf stat -I 1000 -e cycles -a sleep 5
+Print count deltas every N milliseconds (minimum: 10ms)
+The overhead percentage could be high in some cases, for instance with small, sub 100ms intervals. Use with caution.
+ example: 'perf stat -I 1000 -e cycles -a sleep 5'
--per-socket::
Aggregate counts per processor socket for system-wide mode measurements. This
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 602414040344..bf679e2c978b 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -45,6 +45,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
}
for (i = 0; i < argc; ++i) {
+ char *sep, *s;
+
if (strcmp(argv[i], "tracepoint") == 0)
print_tracepoint_events(NULL, NULL, raw_dump);
else if (strcmp(argv[i], "hw") == 0 ||
@@ -60,8 +62,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
print_hwcache_events(NULL, raw_dump);
else if (strcmp(argv[i], "pmu") == 0)
print_pmu_events(NULL, raw_dump);
- else {
- char *sep = strchr(argv[i], ':'), *s;
+ else if ((sep = strchr(argv[i], ':')) != NULL) {
int sep_idx;
if (sep == NULL) {
@@ -76,6 +77,19 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
s[sep_idx] = '\0';
print_tracepoint_events(s, s + sep_idx + 1, raw_dump);
free(s);
+ } else {
+ if (asprintf(&s, "*%s*", argv[i]) < 0) {
+ printf("Critical: Not enough memory! Trying to continue...\n");
+ continue;
+ }
+ print_symbol_events(s, PERF_TYPE_HARDWARE,
+ event_symbols_hw, PERF_COUNT_HW_MAX, raw_dump);
+ print_symbol_events(s, PERF_TYPE_SOFTWARE,
+ event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump);
+ print_hwcache_events(s, raw_dump);
+ print_pmu_events(s, raw_dump);
+ print_tracepoint_events(NULL, s, raw_dump);
+ free(s);
}
}
return 0;
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index f7882ae9ebc6..530c3a28a58c 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -182,10 +182,8 @@ static int opt_set_target(const struct option *opt, const char *str,
if (str) {
if (!strcmp(opt->long_name, "exec"))
params.uprobes = true;
-#ifdef HAVE_DWARF_SUPPORT
else if (!strcmp(opt->long_name, "module"))
params.uprobes = false;
-#endif
else
return ret;
@@ -490,9 +488,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
"file", "vmlinux pathname"),
OPT_STRING('s', "source", &symbol_conf.source_prefix,
"directory", "path to kernel source"),
- OPT_CALLBACK('m', "module", NULL, "modname|path",
- "target module name (for online) or path (for offline)",
- opt_set_target),
OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines,
"Don't search inlined functions"),
#endif
@@ -509,6 +504,9 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
opt_set_filter),
OPT_CALLBACK('x', "exec", NULL, "executable|path",
"target executable name or path", opt_set_target),
+ OPT_CALLBACK('m', "module", NULL, "modname|path",
+ "target module name (for online) or path (for offline)",
+ opt_set_target),
OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
"Enable symbol demangling"),
OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index a01c8ae1ee07..24ace2f318c1 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -49,7 +49,7 @@ struct record {
int realtime_prio;
bool no_buildid;
bool no_buildid_cache;
- long samples;
+ unsigned long long samples;
};
static int record__write(struct record *rec, void *bf, size_t size)
@@ -637,17 +637,25 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
* Let the child rip
*/
if (forks) {
- union perf_event event;
+ union perf_event *event;
+
+ event = malloc(sizeof(event->comm) + machine->id_hdr_size);
+ if (event == NULL) {
+ err = -ENOMEM;
+ goto out_child;
+ }
+
/*
* Some H/W events are generated before COMM event
* which is emitted during exec(), so perf script
* cannot see a correct process name for those events.
* Synthesize COMM event to prevent it.
*/
- perf_event__synthesize_comm(tool, &event,
+ perf_event__synthesize_comm(tool, event,
rec->evlist->workload.pid,
process_synthesized_event,
machine);
+ free(event);
perf_evlist__start_workload(rec->evlist);
}
@@ -659,7 +667,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
auxtrace_snapshot_enabled = 1;
for (;;) {
- int hits = rec->samples;
+ unsigned long long hits = rec->samples;
if (record__mmap_read_all(rec) < 0) {
auxtrace_snapshot_enabled = 0;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a96fb5c3bedb..5ef88f760b12 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1179,7 +1179,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_STRING(0, "post", &post_cmd, "command",
"command to run after to the measured command"),
OPT_UINTEGER('I', "interval-print", &stat_config.interval,
- "print counts at regular interval in ms (>= 100)"),
+ "print counts at regular interval in ms (>= 10)"),
OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
"aggregate counts per processor socket", AGGR_SOCKET),
OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
@@ -1332,9 +1332,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
thread_map__read_comms(evsel_list->threads);
if (interval && interval < 100) {
- pr_err("print interval must be >= 100ms\n");
- parse_options_usage(stat_usage, options, "I", 1);
- goto out;
+ if (interval < 10) {
+ pr_err("print interval must be >= 10ms\n");
+ parse_options_usage(stat_usage, options, "I", 1);
+ goto out;
+ } else
+ pr_warning("print interval < 100ms. "
+ "The overhead percentage could be high in some cases. "
+ "Please proceed with caution.\n");
}
if (perf_evlist__alloc_stats(evsel_list, interval))
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 38d4d6cac823..6f641fd68296 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -857,9 +857,12 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
* TODO: we don't process guest user from host side
* except simple counting.
*/
- /* Fall thru */
- default:
goto next_event;
+ default:
+ if (event->header.type == PERF_RECORD_SAMPLE)
+ goto next_event;
+ machine = &session->machines.host;
+ break;
}
@@ -961,6 +964,9 @@ static int __cmd_top(struct perf_top *top)
if (ret)
goto out_delete;
+ if (perf_session__register_idle_thread(top->session) == NULL)
+ goto out_delete;
+
machine__synthesize_threads(&top->session->machines.host, &opts->target,
top->evlist->threads, false, opts->proc_map_timeout);
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 0cad9e07c5b4..c346b331b892 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1151,7 +1151,7 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog)
struct perf_evsel *evsel = hists_to_evsel(hists);
bool use_callchain;
- if (evsel && !symbol_conf.show_ref_callgraph)
+ if (evsel && symbol_conf.use_callchain && !symbol_conf.show_ref_callgraph)
use_callchain = evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN;
else
use_callchain = symbol_conf.use_callchain;
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 76fe167c359e..5ef90be2a249 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1831,7 +1831,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
}
check_calls:
- if (chain->nr > PERF_MAX_STACK_DEPTH) {
+ if (chain->nr > PERF_MAX_STACK_DEPTH && (int)chain->nr > max_stack) {
pr_warning("corrupted callchain. skipping...\n");
return 0;
}
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 41a356ba3cfe..e4b173dec4b9 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -1008,7 +1008,8 @@ void print_pmu_events(const char *event_glob, bool name_only)
goto out_enomem;
j++;
}
- if (pmu->selectable) {
+ if (pmu->selectable &&
+ (event_glob == NULL || strglobmatch(pmu->name, event_glob))) {
char *s;
if (asprintf(&s, "%s//", pmu->name) < 0)
goto out_enomem;
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 3010abc071ff..b51a8bfb40f9 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2543,7 +2543,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
goto out;
}
- if (!pev->uprobes && !pp->retprobe) {
+ /* Note that the symbols in the kmodule are not relocated */
+ if (!pev->uprobes && !pp->retprobe && !pev->target) {
reloc_sym = kernel_get_ref_reloc_sym();
if (!reloc_sym) {
pr_warning("Relocated base symbol is not found!\n");
@@ -2580,8 +2581,9 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
}
/* Add one probe point */
tp->address = map->unmap_ip(map, sym->start) + pp->offset;
- /* If we found a wrong one, mark it by NULL symbol */
- if (!pev->uprobes &&
+
+ /* Check the kprobe (not in module) is within .text */
+ if (!pev->uprobes && !pev->target &&
kprobe_warn_out_range(sym->name, tp->address)) {
tp->symbol = NULL; /* Skip it */
skipped++;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 84a02eae4394..428149bc64d2 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1311,7 +1311,7 @@ struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
return machine__findnew_thread(&session->machines.host, -1, pid);
}
-static struct thread *perf_session__register_idle_thread(struct perf_session *session)
+struct thread *perf_session__register_idle_thread(struct perf_session *session)
{
struct thread *thread;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index b44afc75d1cc..3e900c0efc73 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -89,6 +89,8 @@ struct machine *perf_session__findnew_machine(struct perf_session *session, pid_
}
struct thread *perf_session__findnew(struct perf_session *session, pid_t pid);
+struct thread *perf_session__register_idle_thread(struct perf_session *session);
+
size_t perf_session__fprintf(struct perf_session *session, FILE *fp);
size_t perf_session__fprintf_dsos(struct perf_session *session, FILE *fp);