Commit c3660884 authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'perf-core-for-mingo' of...

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

New, user visible features:

  - Add --buildid-all option to 'perf record' to avoid processing
    samples, just collecting build-ids for _all_ the DSOs that appears
    in PERF_RECORD_MMAP records (Namhyung Kim)

  - Add some more usage tips to appear in the hists browser
    (top & report) (Namhyung Kim, Andi Kleen)

  - Fix mmap2 event allocation in synthesize code, where we were
    allocating space just for PERF_RECORD_MMAP, the older variant,
    which could lead to corner case problems (Wang Nan)

Infrastructure fixes:

  - Make list.h self-sufficient, removing one more reference to
    kernel headers that lead to recent breakage when some rculist
    change was made in the kernel sources. (Josh Poimboeuf)

    Add missing NORETURN define for parse-options.h in
    tools/lib/subcmd (Josh Poimboeuf)

  - Fallback to srcdir/Documentation/ when not finding tips.txt
    elsewhere (Namhyung Kim)
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 0bd106d2 34b7b0f9
...@@ -8,23 +8,23 @@ include scripts/Makefile.include ...@@ -8,23 +8,23 @@ include scripts/Makefile.include
help: help:
@echo 'Possible targets:' @echo 'Possible targets:'
@echo '' @echo ''
@echo ' acpi - ACPI tools' @echo ' acpi - ACPI tools'
@echo ' cgroup - cgroup tools' @echo ' cgroup - cgroup tools'
@echo ' cpupower - a tool for all things x86 CPU power' @echo ' cpupower - a tool for all things x86 CPU power'
@echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer'
@echo ' hv - tools used when in Hyper-V clients' @echo ' freefall - laptop accelerometer program for disk protection'
@echo ' iio - IIO tools' @echo ' hv - tools used when in Hyper-V clients'
@echo ' lguest - a minimal 32-bit x86 hypervisor' @echo ' iio - IIO tools'
@echo ' perf - Linux performance measurement and analysis tool' @echo ' lguest - a minimal 32-bit x86 hypervisor'
@echo ' selftests - various kernel selftests' @echo ' net - misc networking tools'
@echo ' turbostat - Intel CPU idle stats and freq reporting tool' @echo ' perf - Linux performance measurement and analysis tool'
@echo ' usb - USB testing tools' @echo ' selftests - various kernel selftests'
@echo ' virtio - vhost test module' @echo ' tmon - thermal monitoring and tuning tool'
@echo ' net - misc networking tools' @echo ' turbostat - Intel CPU idle stats and freq reporting tool'
@echo ' vm - misc vm tools' @echo ' usb - USB testing tools'
@echo ' virtio - vhost test module'
@echo ' vm - misc vm tools'
@echo ' x86_energy_perf_policy - Intel energy policy tool' @echo ' x86_energy_perf_policy - Intel energy policy tool'
@echo ' tmon - thermal monitoring and tuning tool'
@echo ' freefall - laptop accelerometer program for disk protection'
@echo '' @echo ''
@echo 'You can do:' @echo 'You can do:'
@echo ' $$ make -C tools/ <tool>_install' @echo ' $$ make -C tools/ <tool>_install'
......
This diff is collapsed.
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#ifndef NORETURN
#define NORETURN __attribute__((__noreturn__))
#endif
enum parse_opt_type { enum parse_opt_type {
/* special types */ /* special types */
OPTION_END, OPTION_END,
......
...@@ -42,6 +42,7 @@ CFLAGS_perf.o += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" \ ...@@ -42,6 +42,7 @@ CFLAGS_perf.o += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" \
-include $(OUTPUT)PERF-VERSION-FILE -include $(OUTPUT)PERF-VERSION-FILE
CFLAGS_builtin-trace.o += -DSTRACE_GROUPS_DIR="BUILD_STR($(STRACE_GROUPS_DIR_SQ))" CFLAGS_builtin-trace.o += -DSTRACE_GROUPS_DIR="BUILD_STR($(STRACE_GROUPS_DIR_SQ))"
CFLAGS_builtin-report.o += -DTIPDIR="BUILD_STR($(tipdir_SQ))" CFLAGS_builtin-report.o += -DTIPDIR="BUILD_STR($(tipdir_SQ))"
CFLAGS_builtin-report.o += -DDOCDIR="BUILD_STR($(srcdir_SQ)/Documentation)"
libperf-y += util/ libperf-y += util/
libperf-y += arch/ libperf-y += arch/
......
...@@ -338,6 +338,9 @@ Options passed to clang when compiling BPF scriptlets. ...@@ -338,6 +338,9 @@ Options passed to clang when compiling BPF scriptlets.
Specify vmlinux path which has debuginfo. Specify vmlinux path which has debuginfo.
(enabled when BPF prologue is on) (enabled when BPF prologue is on)
--buildid-all::
Record build-id of all DSOs regardless whether it's actually hit or not.
SEE ALSO SEE ALSO
-------- --------
linkperf:perf-stat[1], linkperf:perf-list[1] linkperf:perf-stat[1], linkperf:perf-list[1]
...@@ -12,3 +12,18 @@ List events using substring match: perf list <keyword> ...@@ -12,3 +12,18 @@ List events using substring match: perf list <keyword>
To see list of saved events and attributes: perf evlist -v To see list of saved events and attributes: perf evlist -v
Use --symfs <dir> if your symbol files are in non-standard locations Use --symfs <dir> if your symbol files are in non-standard locations
To see callchains in a more compact form: perf report -g folded To see callchains in a more compact form: perf report -g folded
Show individual samples with: perf script
Limit to show entries above 5% only: perf report --percent-limit 5
Profiling branch (mis)predictions with: perf record -b / perf report
Treat branches as callchains: perf report --branch-history
To count events in every 1000 msec: perf stat -I 1000
Print event counts in CSV format with: perf stat -x,
If you have debuginfo enabled, try: perf report -s sym,srcline
For memory address profiling, try: perf mem record / perf mem report
For tracepoint events, try: perf report -s trace_fields
To record callchains for each sample: perf record -g
To record every process run by an user: perf record -u <user>
Skip collecing build-id when recording: perf record -B
To change sampling frequency to 100 Hz: perf record -F 100
See assembly instructions with percentage: perf annotate <symbol>
If you prefer Intel style assembly, try: perf annotate -M intel
...@@ -50,6 +50,7 @@ struct record { ...@@ -50,6 +50,7 @@ struct record {
int realtime_prio; int realtime_prio;
bool no_buildid; bool no_buildid;
bool no_buildid_cache; bool no_buildid_cache;
bool buildid_all;
unsigned long long samples; unsigned long long samples;
}; };
...@@ -362,6 +363,13 @@ static int process_buildids(struct record *rec) ...@@ -362,6 +363,13 @@ static int process_buildids(struct record *rec)
*/ */
symbol_conf.ignore_vmlinux_buildid = true; symbol_conf.ignore_vmlinux_buildid = true;
/*
* If --buildid-all is given, it marks all DSO regardless of hits,
* so no need to process samples.
*/
if (rec->buildid_all)
rec->tool.sample = NULL;
return perf_session__process_events(session); return perf_session__process_events(session);
} }
...@@ -756,12 +764,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) ...@@ -756,12 +764,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
if (!rec->no_buildid) { if (!rec->no_buildid) {
process_buildids(rec); process_buildids(rec);
/*
* We take all buildids when the file contains if (rec->buildid_all)
* AUX area tracing data because we do not decode the
* trace because it would take too long.
*/
if (rec->opts.full_auxtrace)
dsos__hit_all(rec->session); dsos__hit_all(rec->session);
} }
perf_session__write_header(rec->session, rec->evlist, fd, true); perf_session__write_header(rec->session, rec->evlist, fd, true);
...@@ -1138,6 +1142,8 @@ struct option __record_options[] = { ...@@ -1138,6 +1142,8 @@ struct option __record_options[] = {
"options passed to clang when compiling BPF scriptlets"), "options passed to clang when compiling BPF scriptlets"),
OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name, OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
"file", "vmlinux pathname"), "file", "vmlinux pathname"),
OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
"Record build-id of all DSOs regardless of hits"),
OPT_END() OPT_END()
}; };
...@@ -1255,6 +1261,14 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1255,6 +1261,14 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
if (err) if (err)
goto out_symbol_exit; goto out_symbol_exit;
/*
* We take all buildids when the file contains
* AUX area tracing data because we do not decode the
* trace because it would take too long.
*/
if (rec->opts.full_auxtrace)
rec->buildid_all = true;
if (record_opts__config(&rec->opts)) { if (record_opts__config(&rec->opts)) {
err = -EINVAL; err = -EINVAL;
goto out_symbol_exit; goto out_symbol_exit;
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "util/tool.h" #include "util/tool.h"
#include <subcmd/parse-options.h> #include <subcmd/parse-options.h>
#include <subcmd/exec-cmd.h>
#include "util/parse-events.h" #include "util/parse-events.h"
#include "util/thread.h" #include "util/thread.h"
...@@ -433,7 +434,14 @@ static int report__browse_hists(struct report *rep) ...@@ -433,7 +434,14 @@ static int report__browse_hists(struct report *rep)
int ret; int ret;
struct perf_session *session = rep->session; struct perf_session *session = rep->session;
struct perf_evlist *evlist = session->evlist; struct perf_evlist *evlist = session->evlist;
const char *help = perf_tip(TIPDIR); const char *help = perf_tip(system_path(TIPDIR));
if (help == NULL) {
/* fallback for people who don't install perf ;-) */
help = perf_tip(DOCDIR);
if (help == NULL)
help = "Cannot load tips.txt file, please install perf!";
}
switch (use_browser) { switch (use_browser) {
case 1: case 1:
......
...@@ -1588,7 +1588,7 @@ static int add_default_attributes(void) ...@@ -1588,7 +1588,7 @@ static int add_default_attributes(void)
return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
} }
static const char * const recort_usage[] = { static const char * const stat_record_usage[] = {
"perf stat record [<options>]", "perf stat record [<options>]",
NULL, NULL,
}; };
...@@ -1611,7 +1611,7 @@ static int __cmd_record(int argc, const char **argv) ...@@ -1611,7 +1611,7 @@ static int __cmd_record(int argc, const char **argv)
struct perf_session *session; struct perf_session *session;
struct perf_data_file *file = &perf_stat.file; struct perf_data_file *file = &perf_stat.file;
argc = parse_options(argc, argv, stat_options, record_usage, argc = parse_options(argc, argv, stat_options, stat_record_usage,
PARSE_OPT_STOP_AT_NON_OPTION); PARSE_OPT_STOP_AT_NON_OPTION);
if (output_name) if (output_name)
...@@ -1745,7 +1745,7 @@ int process_cpu_map_event(struct perf_tool *tool __maybe_unused, ...@@ -1745,7 +1745,7 @@ int process_cpu_map_event(struct perf_tool *tool __maybe_unused,
return set_maps(st); return set_maps(st);
} }
static const char * const report_usage[] = { static const char * const stat_report_usage[] = {
"perf stat report [<options>]", "perf stat report [<options>]",
NULL, NULL,
}; };
...@@ -1779,7 +1779,7 @@ static int __cmd_report(int argc, const char **argv) ...@@ -1779,7 +1779,7 @@ static int __cmd_report(int argc, const char **argv)
struct stat st; struct stat st;
int ret; int ret;
argc = parse_options(argc, argv, options, report_usage, 0); argc = parse_options(argc, argv, options, stat_report_usage, 0);
if (!input_name || !strlen(input_name)) { if (!input_name || !strlen(input_name)) {
if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode)) if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
......
...@@ -692,6 +692,7 @@ template_dir = share/perf-core/templates ...@@ -692,6 +692,7 @@ template_dir = share/perf-core/templates
STRACE_GROUPS_DIR = share/perf-core/strace/groups STRACE_GROUPS_DIR = share/perf-core/strace/groups
htmldir = share/doc/perf-doc htmldir = share/doc/perf-doc
tipdir = share/doc/perf-tip tipdir = share/doc/perf-tip
srcdir = $(srctree)/tools/perf
ifeq ($(prefix),/usr) ifeq ($(prefix),/usr)
sysconfdir = /etc sysconfdir = /etc
ETC_PERFCONFIG = $(sysconfdir)/perfconfig ETC_PERFCONFIG = $(sysconfdir)/perfconfig
...@@ -722,6 +723,7 @@ tipdir_SQ = $(subst ','\'',$(tipdir)) ...@@ -722,6 +723,7 @@ tipdir_SQ = $(subst ','\'',$(tipdir))
prefix_SQ = $(subst ','\'',$(prefix)) prefix_SQ = $(subst ','\'',$(prefix))
sysconfdir_SQ = $(subst ','\'',$(sysconfdir)) sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
libdir_SQ = $(subst ','\'',$(libdir)) libdir_SQ = $(subst ','\'',$(libdir))
srcdir_SQ = $(subst ','\'',$(srcdir))
ifneq ($(filter /%,$(firstword $(perfexecdir))),) ifneq ($(filter /%,$(firstword $(perfexecdir))),)
perfexec_instdir = $(perfexecdir) perfexec_instdir = $(perfexecdir)
...@@ -776,6 +778,7 @@ $(call detected_var,STRACE_GROUPS_DIR_SQ) ...@@ -776,6 +778,7 @@ $(call detected_var,STRACE_GROUPS_DIR_SQ)
$(call detected_var,prefix_SQ) $(call detected_var,prefix_SQ)
$(call detected_var,perfexecdir_SQ) $(call detected_var,perfexecdir_SQ)
$(call detected_var,tipdir_SQ) $(call detected_var,tipdir_SQ)
$(call detected_var,srcdir_SQ)
$(call detected_var,LIBDIR) $(call detected_var,LIBDIR)
$(call detected_var,GTK_CFLAGS) $(call detected_var,GTK_CFLAGS)
$(call detected_var,PERL_EMBED_CCOPTS) $(call detected_var,PERL_EMBED_CCOPTS)
......
...@@ -480,7 +480,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *help) ...@@ -480,7 +480,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *help)
hists__browser_title(browser->hists, hbt, title, sizeof(title)); hists__browser_title(browser->hists, hbt, title, sizeof(title));
if (ui_browser__show(&browser->b, title, help) < 0) if (ui_browser__show(&browser->b, title, "%s", help) < 0)
return -1; return -1;
while (1) { while (1) {
......
...@@ -503,7 +503,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, ...@@ -503,7 +503,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
if (comm_event == NULL) if (comm_event == NULL)
goto out; goto out;
mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size); mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size);
if (mmap_event == NULL) if (mmap_event == NULL)
goto out_free_comm; goto out_free_comm;
...@@ -577,7 +577,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool, ...@@ -577,7 +577,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
if (comm_event == NULL) if (comm_event == NULL)
goto out; goto out;
mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size); mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size);
if (mmap_event == NULL) if (mmap_event == NULL)
goto out_free_comm; goto out_free_comm;
......
...@@ -126,6 +126,11 @@ static int strlist__parse_list_entry(struct strlist *slist, const char *s, ...@@ -126,6 +126,11 @@ static int strlist__parse_list_entry(struct strlist *slist, const char *s,
err = strlist__load(slist, subst); err = strlist__load(slist, subst);
goto out; goto out;
} }
if (slist->file_only) {
err = -ENOENT;
goto out;
}
} }
err = strlist__add(slist, s); err = strlist__add(slist, s);
...@@ -157,11 +162,13 @@ struct strlist *strlist__new(const char *list, const struct strlist_config *conf ...@@ -157,11 +162,13 @@ struct strlist *strlist__new(const char *list, const struct strlist_config *conf
if (slist != NULL) { if (slist != NULL) {
bool dupstr = true; bool dupstr = true;
bool file_only = false;
const char *dirname = NULL; const char *dirname = NULL;
if (config) { if (config) {
dupstr = !config->dont_dupstr; dupstr = !config->dont_dupstr;
dirname = config->dirname; dirname = config->dirname;
file_only = config->file_only;
} }
rblist__init(&slist->rblist); rblist__init(&slist->rblist);
...@@ -170,6 +177,7 @@ struct strlist *strlist__new(const char *list, const struct strlist_config *conf ...@@ -170,6 +177,7 @@ struct strlist *strlist__new(const char *list, const struct strlist_config *conf
slist->rblist.node_delete = strlist__node_delete; slist->rblist.node_delete = strlist__node_delete;
slist->dupstr = dupstr; slist->dupstr = dupstr;
slist->file_only = file_only;
if (list && strlist__parse_list(slist, list, dirname) != 0) if (list && strlist__parse_list(slist, list, dirname) != 0)
goto out_error; goto out_error;
......
...@@ -13,11 +13,18 @@ struct str_node { ...@@ -13,11 +13,18 @@ struct str_node {
struct strlist { struct strlist {
struct rblist rblist; struct rblist rblist;
bool dupstr; bool dupstr;
bool file_only;
}; };
/*
* @file_only: When dirname is present, only consider entries as filenames,
* that should not be added to the list if dirname/entry is not
* found
*/
struct strlist_config { struct strlist_config {
bool dont_dupstr; bool dont_dupstr;
bool file_only;
const char *dirname; const char *dirname;
}; };
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include <unistd.h> #include <unistd.h>
#include "callchain.h" #include "callchain.h"
#include "strlist.h" #include "strlist.h"
#include <subcmd/exec-cmd.h>
struct callchain_param callchain_param = { struct callchain_param callchain_param = {
.mode = CHAIN_GRAPH_ABS, .mode = CHAIN_GRAPH_ABS,
...@@ -672,14 +671,16 @@ const char *perf_tip(const char *dirpath) ...@@ -672,14 +671,16 @@ const char *perf_tip(const char *dirpath)
struct str_node *node; struct str_node *node;
char *tip = NULL; char *tip = NULL;
struct strlist_config conf = { struct strlist_config conf = {
.dirname = system_path(dirpath) , .dirname = dirpath,
.file_only = true,
}; };
tips = strlist__new("tips.txt", &conf); tips = strlist__new("tips.txt", &conf);
if (tips == NULL || strlist__nr_entries(tips) == 1) { if (tips == NULL)
tip = (char *)"Cannot find tips.txt file"; return errno == ENOENT ? NULL : "Tip: get more memory! ;-p";
if (strlist__nr_entries(tips) == 0)
goto out; goto out;
}
node = strlist__entry(tips, random() % strlist__nr_entries(tips)); node = strlist__entry(tips, random() % strlist__nr_entries(tips));
if (asprintf(&tip, "Tip: %s", node->s) < 0) if (asprintf(&tip, "Tip: %s", node->s) < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment