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

Pull perf/core improvements and fixes:

User visible fixes:

 - Fix documentation of :ppp modifier in 'perf list' (Andi Kleen)

 - Fix silly nodes bitfield bits/bytes length assertion in 'perf bench numa' (Jakub Jelen)

 - Remove redundant CPU output in libtraceevent (Steven Rostedt)

 - Remove 'core_id' check in topology 'perf test' (Sukadev Bhattiprolu)

Infrastructure changes/fixes:

 - Record text offset in dso to calculate objdump address, to use with
   modules in addition to vDSO symbol address calculations (Wang Nan)

 - Move utilities.mak from perf to tools/scripts/ (Arnaldo Carvalho de Melo)

 - Add cpumode to the perf_sample struct, this way we don't need to pass
   the union event to the machine and thread resolving routines, shortening
   function signatures and allowing the future introduction of a way
   to use tracepoint events instead of the unavailable HW cycles counter on
   powerpc guests in perf kvm by just hooking on perf_evsel__parse_sample,
   at the end (Arnaldo Carvalho de Melo)

 - Remove/unexport die() related infrastructure, that at some point will
   finally be removed (Arnaldo Carvalho de Melo)

 - Adopt linux/stringify.h from the kernel sources, not to touch this
   kernel header from tools/ (Arnaldo Carvalho de Melo)

 - Stop using strbuf for things we can instead trivially use libc's asprintf()
   (Arnaldo Carvalho de Melo)

 - Ditch tools/lib/util/abspath.c, its only exported function was used at just
   one place and can be replaced by libc's realpath() (Arnaldo Carvalho de Melo)

 - Use strerror_r() in the llvm infrastructure, tread safe, its what is used
   elsewhere in tools/perf/ (Arnaldo Carvalho de Melo)

Cleanups:

 - Removed misplaced or needless __maybe_unused/export (Arnaldo Carvalho de Melo)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Ingo Molnar
2016-03-24 08:30:25 +01:00
79 changed files with 378 additions and 550 deletions
+12
View File
@@ -0,0 +1,12 @@
#ifndef __LINUX_STRINGIFY_H
#define __LINUX_STRINGIFY_H
/* Indirect stringification. Doing two levels allows the parameter to be a
* macro itself. For example, compile with -DFOO=bar, __stringify(FOO)
* converts to "bar".
*/
#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)
#endif /* !__LINUX_STRINGIFY_H */
+1 -1
View File
@@ -1,5 +1,5 @@
include ../../scripts/Makefile.include
include ../../perf/config/utilities.mak # QUIET_CLEAN
include ../../scripts/utilities.mak # QUIET_CLEAN
ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
+1 -1
View File
@@ -1,5 +1,5 @@
include ../../scripts/Makefile.include
include ../../perf/config/utilities.mak # QUIET_CLEAN
include ../../scripts/utilities.mak # QUIET_CLEAN
ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
+1 -3
View File
@@ -5427,10 +5427,8 @@ void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
}
if (pevent->latency_format) {
trace_seq_printf(s, " %3d", record->cpu);
pevent_data_lat_fmt(pevent, s, record);
} else
trace_seq_printf(s, " [%03d]", record->cpu);
}
if (use_usec_format) {
if (pevent->flags & PEVENT_NSEC_OUTPUT) {
+1 -1
View File
@@ -1,5 +1,5 @@
include ../../scripts/Makefile.include
include ../config/utilities.mak
include ../../scripts/utilities.mak
MAN1_TXT= \
$(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
+4 -2
View File
@@ -40,10 +40,12 @@ address should be. The 'p' modifier can be specified multiple times:
0 - SAMPLE_IP can have arbitrary skid
1 - SAMPLE_IP must have constant skid
2 - SAMPLE_IP requested to have 0 skid
3 - SAMPLE_IP must have 0 skid
3 - SAMPLE_IP must have 0 skid, or uses randomization to avoid
sample shadowing effects.
For Intel systems precise event sampling is implemented with PEBS
which supports up to precise-level 2.
which supports up to precise-level 2, and precise level 3 for
some special cases
On AMD systems it is implemented using IBS (up to precise-level 2).
The precise modifier works with event types 0x76 (cpu-cycles, CPU
+1 -1
View File
@@ -3,7 +3,7 @@ include ../scripts/Makefile.include
# The default target of this Makefile is...
all:
include config/utilities.mak
include ../scripts/utilities.mak
# Define V to have a more verbose compile.
#
+1 -3
View File
@@ -3,9 +3,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../util/header.h"
#include "../../util/util.h"
#include <linux/stringify.h>
#define mfspr(rn) ({unsigned long rval; \
asm volatile("mfspr %0," __stringify(rn) \
+10 -12
View File
@@ -25,19 +25,17 @@
# endif
#endif
extern int bench_numa(int argc, const char **argv, const char *prefix);
extern int bench_sched_messaging(int argc, const char **argv, const char *prefix);
extern int bench_sched_pipe(int argc, const char **argv, const char *prefix);
extern int bench_mem_memcpy(int argc, const char **argv,
const char *prefix __maybe_unused);
extern int bench_mem_memset(int argc, const char **argv, const char *prefix);
extern int bench_futex_hash(int argc, const char **argv, const char *prefix);
extern int bench_futex_wake(int argc, const char **argv, const char *prefix);
extern int bench_futex_wake_parallel(int argc, const char **argv,
const char *prefix);
extern int bench_futex_requeue(int argc, const char **argv, const char *prefix);
int bench_numa(int argc, const char **argv, const char *prefix);
int bench_sched_messaging(int argc, const char **argv, const char *prefix);
int bench_sched_pipe(int argc, const char **argv, const char *prefix);
int bench_mem_memcpy(int argc, const char **argv, const char *prefix);
int bench_mem_memset(int argc, const char **argv, const char *prefix);
int bench_futex_hash(int argc, const char **argv, const char *prefix);
int bench_futex_wake(int argc, const char **argv, const char *prefix);
int bench_futex_wake_parallel(int argc, const char **argv, const char *prefix);
int bench_futex_requeue(int argc, const char **argv, const char *prefix);
/* pi futexes */
extern int bench_futex_lock_pi(int argc, const char **argv, const char *prefix);
int bench_futex_lock_pi(int argc, const char **argv, const char *prefix);
#define BENCH_FORMAT_DEFAULT_STR "default"
#define BENCH_FORMAT_DEFAULT 0
+1 -1
View File
@@ -2,7 +2,7 @@
#ifdef HAVE_ARCH_X86_64_SUPPORT
#define MEMCPY_FN(fn, name, desc) \
extern void *fn(void *, const void *, size_t);
void *fn(void *, const void *, size_t);
#include "mem-memcpy-x86-64-asm-def.h"
+1 -1
View File
@@ -2,7 +2,7 @@
#ifdef HAVE_ARCH_X86_64_SUPPORT
#define MEMSET_FN(fn, name, desc) \
extern void *fn(void *, int, size_t);
void *fn(void *, int, size_t);
#include "mem-memset-x86-64-asm-def.h"
+1 -1
View File
@@ -293,7 +293,7 @@ static void bind_to_memnode(int node)
if (node == -1)
return;
BUG_ON(g->p.nr_nodes > (int)sizeof(nodemask));
BUG_ON(g->p.nr_nodes > (int)sizeof(nodemask)*8);
nodemask = 1L << node;
ret = set_mempolicy(MPOL_BIND, &nodemask, sizeof(nodemask)*8);
+1 -1
View File
@@ -94,7 +94,7 @@ static int process_sample_event(struct perf_tool *tool,
struct addr_location al;
int ret = 0;
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
if (machine__resolve(machine, &al, sample) < 0) {
pr_warning("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
+1 -1
View File
@@ -330,7 +330,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
struct hists *hists = evsel__hists(evsel);
int ret = -1;
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
if (machine__resolve(machine, &al, sample) < 0) {
pr_warning("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
+31 -38
View File
@@ -106,12 +106,14 @@ static void exec_woman_emacs(const char *path, const char *page)
if (!check_emacsclient_version()) {
/* This works only with emacsclient version >= 22. */
struct strbuf man_page = STRBUF_INIT;
char *man_page;
if (!path)
path = "emacsclient";
strbuf_addf(&man_page, "(woman \"%s\")", page);
execlp(path, "emacsclient", "-e", man_page.buf, NULL);
if (asprintf(&man_page, "(woman \"%s\")", page) > 0) {
execlp(path, "emacsclient", "-e", man_page, NULL);
free(man_page);
}
warning("failed to exec '%s': %s", path,
strerror_r(errno, sbuf, sizeof(sbuf)));
}
@@ -122,7 +124,7 @@ static void exec_man_konqueror(const char *path, const char *page)
const char *display = getenv("DISPLAY");
if (display && *display) {
struct strbuf man_page = STRBUF_INIT;
char *man_page;
const char *filename = "kfmclient";
char sbuf[STRERR_BUFSIZE];
@@ -141,8 +143,10 @@ static void exec_man_konqueror(const char *path, const char *page)
filename = file;
} else
path = "kfmclient";
strbuf_addf(&man_page, "man:%s(1)", page);
execlp(path, filename, "newTab", man_page.buf, NULL);
if (asprintf(&man_page, "man:%s(1)", page) > 0) {
execlp(path, filename, "newTab", man_page, NULL);
free(man_page);
}
warning("failed to exec '%s': %s", path,
strerror_r(errno, sbuf, sizeof(sbuf)));
}
@@ -161,11 +165,13 @@ static void exec_man_man(const char *path, const char *page)
static void exec_man_cmd(const char *cmd, const char *page)
{
struct strbuf shell_cmd = STRBUF_INIT;
char sbuf[STRERR_BUFSIZE];
char *shell_cmd;
strbuf_addf(&shell_cmd, "%s %s", cmd, page);
execl("/bin/sh", "sh", "-c", shell_cmd.buf, NULL);
if (asprintf(&shell_cmd, "%s %s", cmd, page) > 0) {
execl("/bin/sh", "sh", "-c", shell_cmd, NULL);
free(shell_cmd);
}
warning("failed to exec '%s': %s", cmd,
strerror_r(errno, sbuf, sizeof(sbuf)));
}
@@ -299,43 +305,33 @@ static int is_perf_command(const char *s)
is_in_cmdlist(&other_cmds, s);
}
static const char *prepend(const char *prefix, const char *cmd)
{
size_t pre_len = strlen(prefix);
size_t cmd_len = strlen(cmd);
char *p = malloc(pre_len + cmd_len + 1);
memcpy(p, prefix, pre_len);
strcpy(p + pre_len, cmd);
return p;
}
static const char *cmd_to_page(const char *perf_cmd)
{
char *s;
if (!perf_cmd)
return "perf";
else if (!prefixcmp(perf_cmd, "perf"))
return perf_cmd;
else
return prepend("perf-", perf_cmd);
return asprintf(&s, "perf-%s", perf_cmd) < 0 ? NULL : s;
}
static void setup_man_path(void)
{
struct strbuf new_path = STRBUF_INIT;
char *new_path;
const char *old_path = getenv("MANPATH");
/* We should always put ':' after our path. If there is no
* old_path, the ':' at the end will let 'man' to try
* system-wide paths after ours to find the manual page. If
* there is old_path, we need ':' as delimiter. */
strbuf_addstr(&new_path, system_path(PERF_MAN_PATH));
strbuf_addch(&new_path, ':');
if (old_path)
strbuf_addstr(&new_path, old_path);
setenv("MANPATH", new_path.buf, 1);
strbuf_release(&new_path);
if (asprintf(&new_path, "%s:%s", system_path(PERF_MAN_PATH), old_path ?: "") > 0) {
setenv("MANPATH", new_path, 1);
free(new_path);
} else {
error("Unable to setup man path");
}
}
static void exec_viewer(const char *name, const char *page)
@@ -380,7 +376,7 @@ static int show_info_page(const char *perf_cmd)
return -1;
}
static int get_html_page_path(struct strbuf *page_path, const char *page)
static int get_html_page_path(char **page_path, const char *page)
{
struct stat st;
const char *html_path = system_path(PERF_HTML_PATH);
@@ -392,10 +388,7 @@ static int get_html_page_path(struct strbuf *page_path, const char *page)
return -1;
}
strbuf_init(page_path, 0);
strbuf_addf(page_path, "%s/%s.html", html_path, page);
return 0;
return asprintf(page_path, "%s/%s.html", html_path, page);
}
/*
@@ -413,12 +406,12 @@ static void open_html(const char *path)
static int show_html_page(const char *perf_cmd)
{
const char *page = cmd_to_page(perf_cmd);
struct strbuf page_path; /* it leaks but we exec bellow */
char *page_path; /* it leaks but we exec bellow */
if (get_html_page_path(&page_path, page) != 0)
if (get_html_page_path(&page_path, page) < 0)
return -1;
open_html(page_path.buf);
open_html(page_path);
return 0;
}
+2 -6
View File
@@ -131,8 +131,7 @@ static int copy_bytes(struct perf_inject *inject, int fd, off_t size)
static s64 perf_event__repipe_auxtrace(struct perf_tool *tool,
union perf_event *event,
struct perf_session *session
__maybe_unused)
struct perf_session *session)
{
struct perf_inject *inject = container_of(tool, struct perf_inject,
tool);
@@ -417,9 +416,6 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
{
struct addr_location al;
struct thread *thread;
u8 cpumode;
cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
thread = machine__findnew_thread(machine, sample->pid, sample->tid);
if (thread == NULL) {
@@ -428,7 +424,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
goto repipe;
}
thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, &al);
thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, &al);
if (al.map != NULL) {
if (!al.map->dso->hit) {
+1 -1
View File
@@ -131,7 +131,7 @@ dump_raw_samples(struct perf_tool *tool,
struct addr_location al;
const char *fmt;
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
if (machine__resolve(machine, &al, sample) < 0) {
fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
return -1;
+2 -1
View File
@@ -41,6 +41,7 @@
#include <dlfcn.h>
#include <linux/bitmap.h>
#include <linux/stringify.h>
struct report {
struct perf_tool tool;
@@ -154,7 +155,7 @@ static int process_sample_event(struct perf_tool *tool,
};
int ret = 0;
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
if (machine__resolve(machine, &al, sample) < 0) {
pr_debug("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
+18 -28
View File
@@ -405,9 +405,7 @@ out:
return 0;
}
static void print_sample_iregs(union perf_event *event __maybe_unused,
struct perf_sample *sample,
struct thread *thread __maybe_unused,
static void print_sample_iregs(struct perf_sample *sample,
struct perf_event_attr *attr)
{
struct regs_dump *regs = &sample->intr_regs;
@@ -476,10 +474,7 @@ mispred_str(struct branch_entry *br)
return br->flags.predicted ? 'P' : 'M';
}
static void print_sample_brstack(union perf_event *event __maybe_unused,
struct perf_sample *sample,
struct thread *thread __maybe_unused,
struct perf_event_attr *attr __maybe_unused)
static void print_sample_brstack(struct perf_sample *sample)
{
struct branch_stack *br = sample->branch_stack;
u64 i;
@@ -498,14 +493,11 @@ static void print_sample_brstack(union perf_event *event __maybe_unused,
}
}
static void print_sample_brstacksym(union perf_event *event __maybe_unused,
struct perf_sample *sample,
struct thread *thread __maybe_unused,
struct perf_event_attr *attr __maybe_unused)
static void print_sample_brstacksym(struct perf_sample *sample,
struct thread *thread)
{
struct branch_stack *br = sample->branch_stack;
struct addr_location alf, alt;
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
u64 i, from, to;
if (!(br && br->nr))
@@ -518,11 +510,11 @@ static void print_sample_brstacksym(union perf_event *event __maybe_unused,
from = br->entries[i].from;
to = br->entries[i].to;
thread__find_addr_map(thread, cpumode, MAP__FUNCTION, from, &alf);
thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf);
if (alf.map)
alf.sym = map__find_symbol(alf.map, alf.addr, NULL);
thread__find_addr_map(thread, cpumode, MAP__FUNCTION, to, &alt);
thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
if (alt.map)
alt.sym = map__find_symbol(alt.map, alt.addr, NULL);
@@ -538,8 +530,7 @@ static void print_sample_brstacksym(union perf_event *event __maybe_unused,
}
static void print_sample_addr(union perf_event *event,
struct perf_sample *sample,
static void print_sample_addr(struct perf_sample *sample,
struct thread *thread,
struct perf_event_attr *attr)
{
@@ -550,7 +541,7 @@ static void print_sample_addr(union perf_event *event,
if (!sample_addr_correlates_sym(attr))
return;
perf_event__preprocess_sample_addr(event, sample, thread, &al);
thread__resolve(thread, &al, sample);
if (PRINT_FIELD(SYM)) {
printf(" ");
@@ -567,8 +558,7 @@ static void print_sample_addr(union perf_event *event,
}
}
static void print_sample_bts(union perf_event *event,
struct perf_sample *sample,
static void print_sample_bts(struct perf_sample *sample,
struct perf_evsel *evsel,
struct thread *thread,
struct addr_location *al)
@@ -598,7 +588,7 @@ static void print_sample_bts(union perf_event *event,
((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
!output[attr->type].user_set)) {
printf(" => ");
print_sample_addr(event, sample, thread, attr);
print_sample_addr(sample, thread, attr);
}
if (print_srcline_last)
@@ -747,7 +737,7 @@ static size_t data_src__printf(u64 data_src)
return printf("%-*s", maxlen, out);
}
static void process_event(struct perf_script *script, union perf_event *event,
static void process_event(struct perf_script *script,
struct perf_sample *sample, struct perf_evsel *evsel,
struct addr_location *al)
{
@@ -776,7 +766,7 @@ static void process_event(struct perf_script *script, union perf_event *event,
print_sample_flags(sample->flags);
if (is_bts_event(attr)) {
print_sample_bts(event, sample, evsel, thread, al);
print_sample_bts(sample, evsel, thread, al);
return;
}
@@ -784,7 +774,7 @@ static void process_event(struct perf_script *script, union perf_event *event,
event_format__print(evsel->tp_format, sample->cpu,
sample->raw_data, sample->raw_size);
if (PRINT_FIELD(ADDR))
print_sample_addr(event, sample, thread, attr);
print_sample_addr(sample, thread, attr);
if (PRINT_FIELD(DATA_SRC))
data_src__printf(sample->data_src);
@@ -804,12 +794,12 @@ static void process_event(struct perf_script *script, union perf_event *event,
}
if (PRINT_FIELD(IREGS))
print_sample_iregs(event, sample, thread, attr);
print_sample_iregs(sample, attr);
if (PRINT_FIELD(BRSTACK))
print_sample_brstack(event, sample, thread, attr);
print_sample_brstack(sample);
else if (PRINT_FIELD(BRSTACKSYM))
print_sample_brstacksym(event, sample, thread, attr);
print_sample_brstacksym(sample, thread);
if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
print_sample_bpf_output(sample);
@@ -905,7 +895,7 @@ static int process_sample_event(struct perf_tool *tool,
return 0;
}
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
if (machine__resolve(machine, &al, sample) < 0) {
pr_err("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
@@ -920,7 +910,7 @@ static int process_sample_event(struct perf_tool *tool,
if (scripting_ops)
scripting_ops->process_event(event, sample, evsel, &al);
else
process_event(scr, event, sample, evsel, &al);
process_event(scr, sample, evsel, &al);
out_put:
addr_location__put(&al);
+1 -1
View File
@@ -489,7 +489,7 @@ static const char *cat_backtrace(union perf_event *event,
if (!chain)
goto exit;
if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
if (machine__resolve(machine, &al, sample) < 0) {
fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
goto exit;

Some files were not shown because too many files have changed in this diff Show More