Commit 538592ff 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/core

Pull perf/core improvements and fixes from Arnaldo:

User visible:

  * Fixup header alignment in 'perf sched latency' output (Ramkumar Ramachandra)

  * Fix off-by-one error in 'perf timechart record' argv handling (Ramkumar Ramachandra)

  * Print the evsel name in the annotate stdio output, prep to fix support
    outputting annotation for multiple events, not just for the first one
    (Arnaldo Carvalho de Melo)

Internals:

  * Use tid in mmap/mmap2 events to find maps (Don Zickus)

  * Record the reason for filtering an address_location (Namhyung Kim)

  * Apply all filters to an addr_location (Namhyung Kim)

  * Merge al->filtered with hist_entry->filtered in report/hists (Namhyung Kim)

  * Fix memory leak when synthesizing thread records (Namhyung Kim)

  * Use ui__has_annotation() in 'report' (Namhyung Kim)

Cleanups:

  * Remove unused thread__find_map function (Jiri Olsa)

  * Remove unused simple_strtoul() function (Ramkumar Ramachandra)

Documentation:

  * Update function names in debug messages (Ramkumar Ramachandra)

  * Update some code references in design.txt (Ramkumar Ramachandra)
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 0afd2d51 a51e87cb
......@@ -231,7 +231,7 @@ static int process_sample_event(struct perf_tool *tool,
return -1;
}
if (al.filtered || (rep->hide_unresolved && al.sym == NULL))
if (rep->hide_unresolved && al.sym == NULL)
return 0;
if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
......@@ -928,7 +928,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
* so don't allocate extra space that won't be used in the stdio
* implementation.
*/
if (use_browser == 1 && sort__has_sym) {
if (ui__has_annotation()) {
symbol_conf.priv_size = sizeof(struct annotation);
machines__set_symbol_filter(&session->machines,
symbol__annotate_init);
......
......@@ -1124,7 +1124,7 @@ static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_
avg = work_list->total_lat / work_list->nb_atoms;
printf("|%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max at: %9.6f s\n",
printf("|%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max at: %13.6f s\n",
(double)work_list->total_runtime / 1e6,
work_list->nb_atoms, (double)avg / 1e6,
(double)work_list->max_lat / 1e6,
......@@ -1527,9 +1527,9 @@ static int perf_sched__lat(struct perf_sched *sched)
perf_sched__sort_lat(sched);
printf("\n ---------------------------------------------------------------------------------------------------------------\n");
printf(" Task | Runtime ms | Switches | Average delay ms | Maximum delay ms | Maximum delay at |\n");
printf(" ---------------------------------------------------------------------------------------------------------------\n");
printf("\n -----------------------------------------------------------------------------------------------------------------\n");
printf(" Task | Runtime ms | Switches | Average delay ms | Maximum delay ms | Maximum delay at |\n");
printf(" -----------------------------------------------------------------------------------------------------------------\n");
next = rb_first(&sched->sorted_atom_root);
......@@ -1541,7 +1541,7 @@ static int perf_sched__lat(struct perf_sched *sched)
next = rb_next(next);
}
printf(" -----------------------------------------------------------------------------------------\n");
printf(" -----------------------------------------------------------------------------------------------------------------\n");
printf(" TOTAL: |%11.3f ms |%9" PRIu64 " |\n",
(double)sched->all_runtime / 1e6, sched->all_count);
......
......@@ -494,7 +494,7 @@ static const char *cat_backtrace(union perf_event *event,
continue;
}
tal.filtered = false;
tal.filtered = 0;
thread__find_addr_location(al.thread, machine, cpumode,
MAP__FUNCTION, ip, &tal);
......@@ -1238,7 +1238,7 @@ static int timechart__record(struct timechart *tchart, int argc, const char **ar
for (i = 0; i < old_power_args_nr; i++)
*p++ = strdup(old_power_args[i]);
for (j = 1; j < (unsigned int)argc; j++)
for (j = 0; j < (unsigned int)argc; j++)
*p++ = argv[j];
return cmd_record(rec_argc, rec_argv, NULL);
......
......@@ -18,7 +18,7 @@ underlying hardware counters.
Performance counters are accessed via special file descriptors.
There's one file descriptor per virtual counter used.
The special file descriptor is opened via the perf_event_open()
The special file descriptor is opened via the sys_perf_event_open()
system call:
int sys_perf_event_open(struct perf_event_attr *hw_event_uptr,
......@@ -82,7 +82,7 @@ machine-specific.
If 'raw_type' is 0, then the 'type' field says what kind of counter
this is, with the following encoding:
enum perf_event_types {
enum perf_type_id {
PERF_TYPE_HARDWARE = 0,
PERF_TYPE_SOFTWARE = 1,
PERF_TYPE_TRACEPOINT = 2,
......@@ -95,7 +95,7 @@ specified by 'event_id':
* Generalized performance counter event types, used by the hw_event.event_id
* parameter of the sys_perf_event_open() syscall:
*/
enum hw_event_ids {
enum perf_hw_id {
/*
* Common hardware events, generalized by the kernel:
*/
......@@ -129,7 +129,7 @@ software events, selected by 'event_id':
* physical and sw events of the kernel (and allow the profiling of them as
* well):
*/
enum sw_event_ids {
enum perf_sw_ids {
PERF_COUNT_SW_CPU_CLOCK = 0,
PERF_COUNT_SW_TASK_CLOCK = 1,
PERF_COUNT_SW_PAGE_FAULTS = 2,
......@@ -230,7 +230,7 @@ these events are recorded in the ring-buffer (see below).
The 'comm' bit allows tracking of process comm data on process creation.
This too is recorded in the ring-buffer (see below).
The 'pid' parameter to the perf_event_open() system call allows the
The 'pid' parameter to the sys_perf_event_open() system call allows the
counter to be specific to a task:
pid == 0: if the pid parameter is zero, the counter is attached to the
......@@ -260,7 +260,7 @@ The 'flags' parameter is currently unused and must be zero.
The 'group_fd' parameter allows counter "groups" to be set up. A
counter group has one counter which is the group "leader". The leader
is created first, with group_fd = -1 in the perf_event_open call
is created first, with group_fd = -1 in the sys_perf_event_open call
that creates it. The rest of the group members are created
subsequently, with group_fd giving the fd of the group leader.
(A single counter on its own is created with group_fd = -1 and is
......
......@@ -101,6 +101,7 @@ static struct machine *setup_fake_machine(struct machines *machines)
.mmap = {
.header = { .misc = PERF_RECORD_MISC_USER, },
.pid = fake_mmap_info[i].pid,
.tid = fake_mmap_info[i].pid,
.start = fake_mmap_info[i].start,
.len = 0x1000ULL,
.pgoff = 0ULL,
......
......@@ -1236,6 +1236,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
struct dso *dso = map->dso;
char *filename;
const char *d_filename;
const char *evsel_name = perf_evsel__name(evsel);
struct annotation *notes = symbol__annotation(sym);
struct disasm_line *pos, *queue = NULL;
u64 start = map__rip_2objdump(map, sym->start);
......@@ -1243,7 +1244,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
int more = 0;
u64 len;
int width = 8;
int namelen;
int namelen, evsel_name_len, graph_dotted_len;
filename = strdup(dso->long_name);
if (!filename)
......@@ -1256,14 +1257,17 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
len = symbol__size(sym);
namelen = strlen(d_filename);
evsel_name_len = strlen(evsel_name);
if (perf_evsel__is_group_event(evsel))
width *= evsel->nr_members;
printf(" %-*.*s| Source code & Disassembly of %s\n",
width, width, "Percent", d_filename);
printf("-%-*.*s-------------------------------------\n",
width+namelen, width+namelen, graph_dotted_line);
printf(" %-*.*s| Source code & Disassembly of %s for %s\n",
width, width, "Percent", d_filename, evsel_name);
graph_dotted_len = width + namelen + evsel_name_len;
printf("-%-*.*s-----------------------------------------\n",
graph_dotted_len, graph_dotted_len, graph_dotted_line);
if (verbose)
symbol__annotate_hits(sym, evsel);
......
#include <linux/types.h>
#include "event.h"
#include "debug.h"
#include "hist.h"
#include "machine.h"
#include "sort.h"
#include "string.h"
......@@ -445,6 +446,9 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
union perf_event *comm_event, *mmap_event, *fork_event;
int err = -1;
if (machine__is_default_guest(machine))
return 0;
comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
if (comm_event == NULL)
goto out;
......@@ -457,9 +461,6 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
if (fork_event == NULL)
goto out_free_mmap;
if (machine__is_default_guest(machine))
return 0;
snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
proc = opendir(proc_path);
......@@ -705,7 +706,7 @@ void thread__find_addr_map(struct thread *thread,
al->thread = thread;
al->addr = addr;
al->cpumode = cpumode;
al->filtered = false;
al->filtered = 0;
if (machine == NULL) {
al->map = NULL;
......@@ -731,11 +732,11 @@ void thread__find_addr_map(struct thread *thread,
if ((cpumode == PERF_RECORD_MISC_GUEST_USER ||
cpumode == PERF_RECORD_MISC_GUEST_KERNEL) &&
!perf_guest)
al->filtered = true;
al->filtered |= (1 << HIST_FILTER__GUEST);
if ((cpumode == PERF_RECORD_MISC_USER ||
cpumode == PERF_RECORD_MISC_KERNEL) &&
!perf_host)
al->filtered = true;
al->filtered |= (1 << HIST_FILTER__HOST);
return;
}
......@@ -792,9 +793,6 @@ int perf_event__preprocess_sample(const union perf_event *event,
if (thread == NULL)
return -1;
if (thread__is_filtered(thread))
goto out_filtered;
dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
/*
* Have we already created the kernel maps for this machine?
......@@ -812,6 +810,10 @@ int perf_event__preprocess_sample(const union perf_event *event,
dump_printf(" ...... dso: %s\n",
al->map ? al->map->dso->long_name :
al->level == 'H' ? "[hypervisor]" : "<not found>");
if (thread__is_filtered(thread))
al->filtered |= (1 << HIST_FILTER__THREAD);
al->sym = NULL;
al->cpu = sample->cpu;
......@@ -823,8 +825,9 @@ int perf_event__preprocess_sample(const union perf_event *event,
dso->short_name) ||
(dso->short_name != dso->long_name &&
strlist__has_entry(symbol_conf.dso_list,
dso->long_name)))))
goto out_filtered;
dso->long_name))))) {
al->filtered |= (1 << HIST_FILTER__DSO);
}
al->sym = map__find_symbol(al->map, al->addr,
machine->symbol_filter);
......@@ -832,12 +835,9 @@ int perf_event__preprocess_sample(const union perf_event *event,
if (symbol_conf.sym_list &&
(!al->sym || !strlist__has_entry(symbol_conf.sym_list,
al->sym->name)))
goto out_filtered;
return 0;
al->sym->name))) {
al->filtered |= (1 << HIST_FILTER__SYMBOL);
}
out_filtered:
al->filtered = true;
return 0;
}
......@@ -1023,7 +1023,7 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
group_fd = get_group_fd(evsel, cpu, thread);
retry_open:
pr_debug2("perf_event_open: pid %d cpu %d group_fd %d flags %#lx\n",
pr_debug2("sys_perf_event_open: pid %d cpu %d group_fd %d flags %#lx\n",
pid, cpus->map[cpu], group_fd, flags);
FD(evsel, cpu, thread) = sys_perf_event_open(&evsel->attr,
......@@ -1032,7 +1032,7 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
group_fd, flags);
if (FD(evsel, cpu, thread) < 0) {
err = -errno;
pr_debug2("perf_event_open failed, error %d\n",
pr_debug2("sys_perf_event_open failed, error %d\n",
err);
goto try_fallback;
}
......
......@@ -13,13 +13,6 @@ static bool hists__filter_entry_by_thread(struct hists *hists,
static bool hists__filter_entry_by_symbol(struct hists *hists,
struct hist_entry *he);
enum hist_filter {
HIST_FILTER__DSO,
HIST_FILTER__THREAD,
HIST_FILTER__PARENT,
HIST_FILTER__SYMBOL,
};
struct callchain_param callchain_param = {
.mode = CHAIN_GRAPH_REL,
.min_percent = 0.5,
......@@ -429,7 +422,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
.weight = weight,
},
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
.filtered = symbol__parent_filter(sym_parent) | al->filtered,
.hists = hists,
.branch_info = bi,
.mem_info = mi,
......
......@@ -14,6 +14,15 @@ struct hist_entry;
struct addr_location;
struct symbol;
enum hist_filter {
HIST_FILTER__DSO,
HIST_FILTER__THREAD,
HIST_FILTER__PARENT,
HIST_FILTER__SYMBOL,
HIST_FILTER__GUEST,
HIST_FILTER__HOST,
};
/*
* The kernel collects the number of events it couldn't send in a stretch and
* when possible sends this number in a PERF_RECORD_LOST event. The number of
......
......@@ -94,12 +94,6 @@ static inline int scnprintf(char * buf, size_t size, const char * fmt, ...)
return (i >= ssize) ? (ssize - 1) : i;
}
static inline unsigned long
simple_strtoul(const char *nptr, char **endptr, int base)
{
return strtoul(nptr, endptr, base);
}
int eprintf(int level,
const char *fmt, ...) __attribute__((format(printf, 2, 3)));
......
......@@ -1027,7 +1027,7 @@ int machine__process_mmap2_event(struct machine *machine,
}
thread = machine__findnew_thread(machine, event->mmap2.pid,
event->mmap2.pid);
event->mmap2.tid);
if (thread == NULL)
goto out_problem;
......@@ -1075,7 +1075,7 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
}
thread = machine__findnew_thread(machine, event->mmap.pid,
event->mmap.pid);
event->mmap.tid);
if (thread == NULL)
goto out_problem;
......@@ -1312,7 +1312,7 @@ static int machine__resolve_callchain_sample(struct machine *machine,
continue;
}
al.filtered = false;
al.filtered = 0;
thread__find_addr_location(thread, machine, cpumode,
MAP__FUNCTION, ip, &al);
if (al.sym != NULL) {
......
......@@ -186,7 +186,7 @@ struct addr_location {
struct symbol *sym;
u64 addr;
char level;
bool filtered;
u8 filtered;
u8 cpumode;
s32 cpu;
};
......
......@@ -44,12 +44,6 @@ void thread__insert_map(struct thread *thread, struct map *map);
int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
size_t thread__fprintf(struct thread *thread, FILE *fp);
static inline struct map *thread__find_map(struct thread *thread,
enum map_type type, u64 addr)
{
return thread ? map_groups__find(&thread->mg, type, addr) : NULL;
}
void thread__find_addr_map(struct thread *thread, struct machine *machine,
u8 cpumode, enum map_type type, u64 addr,
struct addr_location *al);
......
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