Skip to content

Commit

Permalink
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/acme/linux into perf/core

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

User visible changes:

  - Add hint for 'Too many events are opened.' error message (Jiri Olsa)

Infrastructure changes:

  - Protect accesses to map rbtrees with a lock and refcount struct map,
    reducing memory usage as maps not used get freed. The 'dso' struct is
    next in line. (Arnaldo Carvalho de Melo)

  - Annotation and branch related option parsing refactorings to
    share code with upcoming patches (Andi Kleen)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed May 28, 2015
2 parents 09a216e + f00898f commit f1942b9
Show file tree
Hide file tree
Showing 15 changed files with 315 additions and 174 deletions.
4 changes: 4 additions & 0 deletions tools/perf/builtin-annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
(al->sym == NULL ||
strcmp(ann->sym_hist_filter, al->sym->name) != 0)) {
/* We're only interested in a symbol named sym_hist_filter */
/*
* FIXME: why isn't this done in the symbol_filter when loading
* the DSO?
*/
if (al->sym != NULL) {
rb_erase(&al->sym->rb_node,
&al->map->dso->symbols[al->map->type]);
Expand Down
89 changes: 1 addition & 88 deletions tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "util/thread_map.h"
#include "util/data.h"
#include "util/auxtrace.h"
#include "util/parse-branch-options.h"

#include <unistd.h>
#include <sched.h>
Expand Down Expand Up @@ -751,94 +752,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
return status;
}

#define BRANCH_OPT(n, m) \
{ .name = n, .mode = (m) }

#define BRANCH_END { .name = NULL }

struct branch_mode {
const char *name;
int mode;
};

static const struct branch_mode branch_modes[] = {
BRANCH_OPT("u", PERF_SAMPLE_BRANCH_USER),
BRANCH_OPT("k", PERF_SAMPLE_BRANCH_KERNEL),
BRANCH_OPT("hv", PERF_SAMPLE_BRANCH_HV),
BRANCH_OPT("any", PERF_SAMPLE_BRANCH_ANY),
BRANCH_OPT("any_call", PERF_SAMPLE_BRANCH_ANY_CALL),
BRANCH_OPT("any_ret", PERF_SAMPLE_BRANCH_ANY_RETURN),
BRANCH_OPT("ind_call", PERF_SAMPLE_BRANCH_IND_CALL),
BRANCH_OPT("abort_tx", PERF_SAMPLE_BRANCH_ABORT_TX),
BRANCH_OPT("in_tx", PERF_SAMPLE_BRANCH_IN_TX),
BRANCH_OPT("no_tx", PERF_SAMPLE_BRANCH_NO_TX),
BRANCH_OPT("cond", PERF_SAMPLE_BRANCH_COND),
BRANCH_END
};

static int
parse_branch_stack(const struct option *opt, const char *str, int unset)
{
#define ONLY_PLM \
(PERF_SAMPLE_BRANCH_USER |\
PERF_SAMPLE_BRANCH_KERNEL |\
PERF_SAMPLE_BRANCH_HV)

uint64_t *mode = (uint64_t *)opt->value;
const struct branch_mode *br;
char *s, *os = NULL, *p;
int ret = -1;

if (unset)
return 0;

/*
* cannot set it twice, -b + --branch-filter for instance
*/
if (*mode)
return -1;

/* str may be NULL in case no arg is passed to -b */
if (str) {
/* because str is read-only */
s = os = strdup(str);
if (!s)
return -1;

for (;;) {
p = strchr(s, ',');
if (p)
*p = '\0';

for (br = branch_modes; br->name; br++) {
if (!strcasecmp(s, br->name))
break;
}
if (!br->name) {
ui__warning("unknown branch filter %s,"
" check man page\n", s);
goto error;
}

*mode |= br->mode;

if (!p)
break;

s = p + 1;
}
}
ret = 0;

/* default to any branch */
if ((*mode & ~ONLY_PLM) == 0) {
*mode = PERF_SAMPLE_BRANCH_ANY;
}
error:
free(os);
return ret;
}

static void callchain_debug(void)
{
static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/tests/vmlinux-kallsyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ int test__vmlinux_matches_kallsyms(void)
struct map *kallsyms_map, *vmlinux_map, *map;
struct machine kallsyms, vmlinux;
enum map_type type = MAP__FUNCTION;
struct rb_root *maps = &vmlinux.kmaps.maps[type];
struct maps *maps = &vmlinux.kmaps.maps[type];
u64 mem_start, mem_end;

/*
Expand Down
1 change: 1 addition & 0 deletions tools/perf/util/Build
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ libperf-$(CONFIG_X86) += tsc.o
libperf-y += cloexec.o
libperf-y += thread-stack.o
libperf-$(CONFIG_AUXTRACE) += auxtrace.o
libperf-y += parse-branch-options.o

libperf-$(CONFIG_LIBELF) += symbol-elf.o
libperf-$(CONFIG_LIBELF) += probe-event.o
Expand Down
21 changes: 14 additions & 7 deletions tools/perf/util/annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,20 +506,27 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,
return 0;
}

static struct annotation *symbol__get_annotation(struct symbol *sym)
{
struct annotation *notes = symbol__annotation(sym);

if (notes->src == NULL) {
if (symbol__alloc_hist(sym) < 0)
return NULL;
}
return notes;
}

static int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
int evidx, u64 addr)
{
struct annotation *notes;

if (sym == NULL)
return 0;

notes = symbol__annotation(sym);
if (notes->src == NULL) {
if (symbol__alloc_hist(sym) < 0)
return -ENOMEM;
}

notes = symbol__get_annotation(sym);
if (notes == NULL)
return -ENOMEM;
return __symbol__inc_addr_samples(sym, map, notes, evidx, addr);
}

Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ int perf_event__synthesize_modules(struct perf_tool *tool,
int rc = 0;
struct map *pos;
struct map_groups *kmaps = &machine->kmaps;
struct rb_root *maps = &kmaps->maps[MAP__FUNCTION];
struct maps *maps = &kmaps->maps[MAP__FUNCTION];
union perf_event *event = zalloc((sizeof(event->mmap) +
machine->id_hdr_size));
if (event == NULL) {
Expand Down
4 changes: 3 additions & 1 deletion tools/perf/util/evsel.c
Original file line number Diff line number Diff line change
Expand Up @@ -2149,7 +2149,9 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
case EMFILE:
return scnprintf(msg, size, "%s",
"Too many events are opened.\n"
"Try again after reducing the number of events.");
"Probably the maximum number of open file descriptors has been reached.\n"
"Hint: Try again after reducing the number of events.\n"
"Hint: Try increasing the limit with 'ulimit -n <limit>'");
case ENODEV:
if (target->cpu_list)
return scnprintf(msg, size, "%s",
Expand Down
3 changes: 2 additions & 1 deletion tools/perf/util/machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,6 @@ void machine__destroy_kernel_maps(struct machine *machine)
kmap->ref_reloc_sym = NULL;
}

map__delete(machine->vmlinux_maps[type]);
machine->vmlinux_maps[type] = NULL;
}
}
Expand Down Expand Up @@ -1247,6 +1246,7 @@ int machine__process_mmap2_event(struct machine *machine,

thread__insert_map(thread, map);
thread__put(thread);
map__put(map);
return 0;

out_problem_map:
Expand Down Expand Up @@ -1297,6 +1297,7 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event

thread__insert_map(thread, map);
thread__put(thread);
map__put(map);
return 0;

out_problem_map:
Expand Down
Loading

0 comments on commit f1942b9

Please sign in to comment.