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 improvements and fixes from Arnaldo Carvalho de Melo:

User visible changes:

  o Restore "--callchain graph" output, broken in recent cset to end
    up being the same as "fractal" (Namhyung Kim)

  o Allow profiling when kptr_restrict == 1 for non root users,
    kernel samples will just remain unresolved (Andi Kleen)

  o Allow configuring default options for callchains in config file (Namhyung Kim)

  o Fix line number in the config file error message (Jiri Olsa)

  o Fix --per-core on multi socket systems (Andi Kleen)

Cleanups:

  o Use ACCESS_ONCE() instead of volatile cast. (Pranith Kumar)

  o Modify error code for when perf_session__new() fails (Taeung Song)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed Sep 27, 2014
2 parents cf8102f + 49757c9 commit 07394b5
Show file tree
Hide file tree
Showing 24 changed files with 241 additions and 163 deletions.
2 changes: 1 addition & 1 deletion tools/perf/builtin-annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)

annotate.session = perf_session__new(&file, false, &annotate.tool);
if (annotate.session == NULL)
return -ENOMEM;
return -1;

symbol_conf.priv_size = sizeof(struct annotation);
symbol_conf.try_vmlinux_path = true;
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ static int __cmd_diff(void)
d->session = perf_session__new(&d->file, false, &tool);
if (!d->session) {
pr_err("Failed to open %s\n", d->file.path);
ret = -ENOMEM;
ret = -1;
goto out_delete;
}

Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-evlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details

session = perf_session__new(&file, 0, NULL);
if (session == NULL)
return -ENOMEM;
return -1;

evlist__for_each(session->evlist, pos)
perf_evsel__fprintf(pos, details, stdout);
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-inject.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
file.path = inject.input_name;
inject.session = perf_session__new(&file, true, &inject.tool);
if (inject.session == NULL)
return -ENOMEM;
return -1;

if (symbol__init(&inject.session->header.env) < 0)
return -1;
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-kmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)

session = perf_session__new(&file, false, &perf_kmem);
if (session == NULL)
return -ENOMEM;
return -1;

symbol__init(&session->header.env);

Expand Down
4 changes: 2 additions & 2 deletions tools/perf/builtin-kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1058,7 +1058,7 @@ static int read_events(struct perf_kvm_stat *kvm)
kvm->session = perf_session__new(&file, false, &kvm->tool);
if (!kvm->session) {
pr_err("Initializing perf session failed\n");
return -EINVAL;
return -1;
}

symbol__init(&kvm->session->header.env);
Expand Down Expand Up @@ -1361,7 +1361,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
*/
kvm->session = perf_session__new(&file, false, &kvm->tool);
if (kvm->session == NULL) {
err = -ENOMEM;
err = -1;
goto out;
}
kvm->session->evlist = kvm->evlist;
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ static int __cmd_report(bool display_info)
session = perf_session__new(&file, false, &eops);
if (!session) {
pr_err("Initializing perf session failed\n");
return -ENOMEM;
return -1;
}

symbol__init(&session->header.env);
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static int report_raw_events(struct perf_mem *mem)
&mem->tool);

if (session == NULL)
return -ENOMEM;
return -1;

if (mem->cpu_list) {
ret = perf_session__cpu_bitmap(session, mem->cpu_list,
Expand Down
119 changes: 15 additions & 104 deletions tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,145 +624,56 @@ parse_branch_stack(const struct option *opt, const char *str, int unset)
return ret;
}

#ifdef HAVE_DWARF_UNWIND_SUPPORT
static int get_stack_size(char *str, unsigned long *_size)
{
char *endptr;
unsigned long size;
unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));

size = strtoul(str, &endptr, 0);

do {
if (*endptr)
break;

size = round_up(size, sizeof(u64));
if (!size || size > max_size)
break;

*_size = size;
return 0;

} while (0);

pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
max_size, str);
return -1;
}
#endif /* HAVE_DWARF_UNWIND_SUPPORT */

int record_parse_callchain(const char *arg, struct record_opts *opts)
{
char *tok, *name, *saveptr = NULL;
char *buf;
int ret = -1;

/* We need buffer that we know we can write to. */
buf = malloc(strlen(arg) + 1);
if (!buf)
return -ENOMEM;

strcpy(buf, arg);

tok = strtok_r((char *)buf, ",", &saveptr);
name = tok ? : (char *)buf;

do {
/* Framepointer style */
if (!strncmp(name, "fp", sizeof("fp"))) {
if (!strtok_r(NULL, ",", &saveptr)) {
opts->call_graph = CALLCHAIN_FP;
ret = 0;
} else
pr_err("callchain: No more arguments "
"needed for -g fp\n");
break;

#ifdef HAVE_DWARF_UNWIND_SUPPORT
/* Dwarf style */
} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
const unsigned long default_stack_dump_size = 8192;

ret = 0;
opts->call_graph = CALLCHAIN_DWARF;
opts->stack_dump_size = default_stack_dump_size;

tok = strtok_r(NULL, ",", &saveptr);
if (tok) {
unsigned long size = 0;

ret = get_stack_size(tok, &size);
opts->stack_dump_size = size;
}
#endif /* HAVE_DWARF_UNWIND_SUPPORT */
} else {
pr_err("callchain: Unknown --call-graph option "
"value: %s\n", arg);
break;
}

} while (0);

free(buf);
return ret;
}

static void callchain_debug(struct record_opts *opts)
static void callchain_debug(void)
{
static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF" };

pr_debug("callchain: type %s\n", str[opts->call_graph]);
pr_debug("callchain: type %s\n", str[callchain_param.record_mode]);

if (opts->call_graph == CALLCHAIN_DWARF)
if (callchain_param.record_mode == CALLCHAIN_DWARF)
pr_debug("callchain: stack dump size %d\n",
opts->stack_dump_size);
callchain_param.dump_size);
}

int record_parse_callchain_opt(const struct option *opt,
int record_parse_callchain_opt(const struct option *opt __maybe_unused,
const char *arg,
int unset)
{
struct record_opts *opts = opt->value;
int ret;

opts->call_graph_enabled = !unset;
callchain_param.enabled = !unset;

/* --no-call-graph */
if (unset) {
opts->call_graph = CALLCHAIN_NONE;
callchain_param.record_mode = CALLCHAIN_NONE;
pr_debug("callchain: disabled\n");
return 0;
}

ret = record_parse_callchain(arg, opts);
ret = parse_callchain_record_opt(arg);
if (!ret)
callchain_debug(opts);
callchain_debug();

return ret;
}

int record_callchain_opt(const struct option *opt,
int record_callchain_opt(const struct option *opt __maybe_unused,
const char *arg __maybe_unused,
int unset __maybe_unused)
{
struct record_opts *opts = opt->value;
callchain_param.enabled = true;

opts->call_graph_enabled = !unset;
if (callchain_param.record_mode == CALLCHAIN_NONE)
callchain_param.record_mode = CALLCHAIN_FP;

if (opts->call_graph == CALLCHAIN_NONE)
opts->call_graph = CALLCHAIN_FP;

callchain_debug(opts);
callchain_debug();
return 0;
}

static int perf_record_config(const char *var, const char *value, void *cb)
{
struct record *rec = cb;

if (!strcmp(var, "record.call-graph"))
return record_parse_callchain(value, &rec->opts);
var = "call-graph.record-mode"; /* fall-through */

return perf_default_config(var, value, cb);
}
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
repeat:
session = perf_session__new(&file, false, &report.tool);
if (session == NULL)
return -ENOMEM;
return -1;

if (report.queue_size) {
ordered_events__set_alloc_size(&session->ordered_events,
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-script.c
Original file line number Diff line number Diff line change
Expand Up @@ -1744,7 +1744,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)

session = perf_session__new(&file, false, &script.tool);
if (session == NULL)
return -ENOMEM;
return -1;

if (header || header_only) {
perf_session__fprintf_info(session, stdout, show_full_info);
Expand Down
9 changes: 5 additions & 4 deletions tools/perf/builtin-stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
}
}

static void nsec_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
{
double msecs = avg / 1e6;
const char *fmt_v, *fmt_n;
Expand All @@ -741,7 +741,7 @@ static void nsec_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
fmt_v = csv_output ? "%.6f%s" : "%18.6f%s";
fmt_n = csv_output ? "%s" : "%-25s";

aggr_printout(evsel, cpu, nr);
aggr_printout(evsel, id, nr);

scnprintf(name, sizeof(name), "%s%s",
perf_evsel__name(evsel), csv_output ? "" : " (msec)");
Expand Down Expand Up @@ -947,11 +947,12 @@ static void print_ll_cache_misses(int cpu,
fprintf(output, " of all LL-cache hits ");
}

static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
{
double total, ratio = 0.0, total2;
double sc = evsel->scale;
const char *fmt;
int cpu = cpu_map__id_to_cpu(id);

if (csv_output) {
fmt = sc != 1.0 ? "%.2f%s" : "%.0f%s";
Expand All @@ -962,7 +963,7 @@ static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
}

aggr_printout(evsel, cpu, nr);
aggr_printout(evsel, id, nr);

if (aggr_mode == AGGR_GLOBAL)
cpu = 0;
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-timechart.c
Original file line number Diff line number Diff line change
Expand Up @@ -1605,7 +1605,7 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name)
int ret = -EINVAL;

if (session == NULL)
return -ENOMEM;
return -1;

symbol__init(&session->header.env);

Expand Down
6 changes: 2 additions & 4 deletions tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,7 @@ static int __cmd_top(struct perf_top *top)

top->session = perf_session__new(NULL, false, NULL);
if (top->session == NULL)
return -ENOMEM;
return -1;

machines__set_symbol_filter(&top->session->machines, symbol_filter);

Expand Down Expand Up @@ -1020,10 +1020,8 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)

static int perf_top_config(const char *var, const char *value, void *cb)
{
struct perf_top *top = cb;

if (!strcmp(var, "top.call-graph"))
return record_parse_callchain(value, &top->record_opts);
var = "call-graph.record-mode"; /* fall-through */
if (!strcmp(var, "top.children")) {
symbol_conf.cumulate_callchain = perf_config_bool(var, value);
return 0;
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -2250,7 +2250,7 @@ static int trace__replay(struct trace *trace)

session = perf_session__new(&file, false, &trace->tool);
if (session == NULL)
return -ENOMEM;
return -1;

if (symbol__init(&session->header.env) < 0)
goto out;
Expand Down
3 changes: 0 additions & 3 deletions tools/perf/perf.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ void pthread__unblock_sigwinch(void);

struct record_opts {
struct target target;
int call_graph;
bool call_graph_enabled;
bool group;
bool inherit_stat;
bool no_buffering;
Expand All @@ -60,7 +58,6 @@ struct record_opts {
u64 branch_stack;
u64 default_interval;
u64 user_interval;
u16 stack_dump_size;
bool sample_transaction;
unsigned initial_delay;
};
Expand Down
3 changes: 0 additions & 3 deletions tools/perf/ui/browsers/hists.c
Original file line number Diff line number Diff line change
Expand Up @@ -804,9 +804,6 @@ static int hist_browser__show_entry(struct hist_browser *browser,
.is_current_entry = current_entry,
};

if (symbol_conf.cumulate_callchain)
total = entry->stat_acc->period;

printed += hist_browser__show_callchain(browser,
&entry->sorted_chain, 1, row, total,
hist_browser__show_callchain_entry, &arg,
Expand Down
Loading

0 comments on commit 07394b5

Please sign in to comment.