Merge branch 'perf/core' of git://github.com/acmel/linux into perf/core

This commit is contained in:
Ingo Molnar 2011-12-20 20:32:37 +01:00
commit d9e24427f3
12 changed files with 160 additions and 24 deletions

View file

@ -80,9 +80,10 @@ OPTIONS
--dump-raw-trace:: --dump-raw-trace::
Dump raw trace in ASCII. Dump raw trace in ASCII.
-g [type,min,order]:: -g [type,min[,limit],order]::
--call-graph:: --call-graph::
Display call chains using type, min percent threshold and order. Display call chains using type, min percent threshold, optional print
limit and order.
type can be either: type can be either:
- flat: single column, linear exposure of call chains. - flat: single column, linear exposure of call chains.
- graph: use a graph tree, displaying absolute overhead rates. - graph: use a graph tree, displaying absolute overhead rates.

View file

@ -700,6 +700,7 @@ const struct option record_options[] = {
OPT_BOOLEAN('d', "data", &record.opts.sample_address, OPT_BOOLEAN('d', "data", &record.opts.sample_address,
"Sample addresses"), "Sample addresses"),
OPT_BOOLEAN('T', "timestamp", &record.opts.sample_time, "Sample timestamps"), OPT_BOOLEAN('T', "timestamp", &record.opts.sample_time, "Sample timestamps"),
OPT_BOOLEAN('P', "period", &record.opts.period, "Sample period"),
OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples, OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
"don't sample"), "don't sample"),
OPT_BOOLEAN('N', "no-buildid-cache", &record.no_buildid_cache, OPT_BOOLEAN('N', "no-buildid-cache", &record.no_buildid_cache,

View file

@ -407,7 +407,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
goto setup; goto setup;
if (tok2[0] != 'c') { if (tok2[0] != 'c') {
callchain_param.print_limit = strtod(tok2, &endptr); callchain_param.print_limit = strtoul(tok2, &endptr, 0);
tok2 = strtok(NULL, ","); tok2 = strtok(NULL, ",");
if (!tok2) if (!tok2)
goto setup; goto setup;
@ -485,8 +485,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
"regex filter to identify parent, see: '--sort parent'"), "regex filter to identify parent, see: '--sort parent'"),
OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other, OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
"Only display entries with parent-match"), "Only display entries with parent-match"),
OPT_CALLBACK_DEFAULT('g', "call-graph", &report, "output_type,min_percent, call_order", OPT_CALLBACK_DEFAULT('g', "call-graph", &report, "output_type,min_percent[,print_limit],call_order",
"Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold and callchain order. " "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold, optional print limit and callchain order. "
"Default: fractal,0.5,callee", &parse_callchain_opt, callchain_default_opt), "Default: fractal,0.5,callee", &parse_callchain_opt, callchain_default_opt),
OPT_BOOLEAN('G', "inverted", &report.inverted_callchain, OPT_BOOLEAN('G', "inverted", &report.inverted_callchain,
"alias for inverted call graph"), "alias for inverted call graph"),

View file

@ -603,7 +603,7 @@ static int test__basic_mmap(void)
#define TEST_ASSERT_VAL(text, cond) \ #define TEST_ASSERT_VAL(text, cond) \
do { \ do { \
if (!cond) { \ if (!(cond)) { \
pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \ pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \
return -1; \ return -1; \
} \ } \
@ -759,6 +759,103 @@ static int test__checkevent_breakpoint_w(struct perf_evlist *evlist)
return 0; return 0;
} }
static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
return test__checkevent_tracepoint(evlist);
}
static int
test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;
TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
list_for_each_entry(evsel, &evlist->entries, node) {
TEST_ASSERT_VAL("wrong exclude_user",
!evsel->attr.exclude_user);
TEST_ASSERT_VAL("wrong exclude_kernel",
evsel->attr.exclude_kernel);
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
}
return test__checkevent_tracepoint_multi(evlist);
}
static int test__checkevent_raw_modifier(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
return test__checkevent_raw(evlist);
}
static int test__checkevent_numeric_modifier(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
return test__checkevent_numeric(evlist);
}
static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
return test__checkevent_symbolic_name(evlist);
}
static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
return test__checkevent_symbolic_alias(evlist);
}
static int test__checkevent_genhw_modifier(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
return test__checkevent_genhw(evlist);
}
static struct test__event_st { static struct test__event_st {
const char *name; const char *name;
__u32 type; __u32 type;
@ -808,6 +905,34 @@ static struct test__event_st {
.name = "mem:0:w", .name = "mem:0:w",
.check = test__checkevent_breakpoint_w, .check = test__checkevent_breakpoint_w,
}, },
{
.name = "syscalls:sys_enter_open:k",
.check = test__checkevent_tracepoint_modifier,
},
{
.name = "syscalls:*:u",
.check = test__checkevent_tracepoint_multi_modifier,
},
{
.name = "r1:kp",
.check = test__checkevent_raw_modifier,
},
{
.name = "1:1:hp",
.check = test__checkevent_numeric_modifier,
},
{
.name = "instructions:h",
.check = test__checkevent_symbolic_name_modifier,
},
{
.name = "faults:u",
.check = test__checkevent_symbolic_alias_modifier,
},
{
.name = "L1-dcache-load-miss:kp",
.check = test__checkevent_genhw_modifier,
},
}; };
#define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st)) #define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st))

View file

@ -200,6 +200,7 @@ struct perf_record_opts {
bool sample_time; bool sample_time;
bool sample_id_all_avail; bool sample_id_all_avail;
bool system_wide; bool system_wide;
bool period;
unsigned int freq; unsigned int freq;
unsigned int mmap_pages; unsigned int mmap_pages;
unsigned int user_freq; unsigned int user_freq;

View file

@ -1,5 +1,8 @@
/* /*
* GIT - The information manager from hell * config.c
*
* Helper functions for parsing config items.
* Originally copied from GIT source.
* *
* Copyright (C) Linus Torvalds, 2005 * Copyright (C) Linus Torvalds, 2005
* Copyright (C) Johannes Schindelin, 2005 * Copyright (C) Johannes Schindelin, 2005

View file

@ -814,13 +814,14 @@ int perf_event__preprocess_sample(const union perf_event *event,
al->cpu = sample->cpu; al->cpu = sample->cpu;
if (al->map) { if (al->map) {
struct dso *dso = al->map->dso;
if (symbol_conf.dso_list && if (symbol_conf.dso_list &&
(!al->map || !al->map->dso || (!dso || !(strlist__has_entry(symbol_conf.dso_list,
!(strlist__has_entry(symbol_conf.dso_list, dso->short_name) ||
al->map->dso->short_name) || (dso->short_name != dso->long_name &&
(al->map->dso->short_name != al->map->dso->long_name && strlist__has_entry(symbol_conf.dso_list,
strlist__has_entry(symbol_conf.dso_list, dso->long_name)))))
al->map->dso->long_name)))))
goto out_filtered; goto out_filtered;
al->sym = map__find_symbol(al->map, al->addr, filter); al->sym = map__find_symbol(al->map, al->addr, filter);

View file

@ -447,8 +447,10 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist,
evlist->mmap[idx].mask = mask; evlist->mmap[idx].mask = mask;
evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot, evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
MAP_SHARED, fd, 0); MAP_SHARED, fd, 0);
if (evlist->mmap[idx].base == MAP_FAILED) if (evlist->mmap[idx].base == MAP_FAILED) {
evlist->mmap[idx].base = NULL;
return -1; return -1;
}
perf_evlist__add_pollfd(evlist, fd); perf_evlist__add_pollfd(evlist, fd);
return 0; return 0;

View file

@ -108,6 +108,9 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts)
if (opts->system_wide) if (opts->system_wide)
attr->sample_type |= PERF_SAMPLE_CPU; attr->sample_type |= PERF_SAMPLE_CPU;
if (opts->period)
attr->sample_type |= PERF_SAMPLE_PERIOD;
if (opts->sample_id_all_avail && if (opts->sample_id_all_avail &&
(opts->sample_time || opts->system_wide || (opts->sample_time || opts->system_wide ||
!opts->no_inherit || opts->cpu_list)) !opts->no_inherit || opts->cpu_list))
@ -457,7 +460,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
u32 val32[2]; u32 val32[2];
} u; } u;
memset(data, 0, sizeof(*data));
data->cpu = data->pid = data->tid = -1; data->cpu = data->pid = data->tid = -1;
data->stream_id = data->id = data->time = -1ULL; data->stream_id = data->id = data->time = -1ULL;

View file

@ -1757,7 +1757,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,
struct stat st; struct stat st;
/*sshfs might return bad dent->d_type, so we have to stat*/ /*sshfs might return bad dent->d_type, so we have to stat*/
sprintf(path, "%s/%s", dir_name, dent->d_name); snprintf(path, sizeof(path), "%s/%s", dir_name, dent->d_name);
if (stat(path, &st)) if (stat(path, &st))
continue; continue;
@ -1766,8 +1766,6 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,
!strcmp(dent->d_name, "..")) !strcmp(dent->d_name, ".."))
continue; continue;
snprintf(path, sizeof(path), "%s/%s",
dir_name, dent->d_name);
ret = map_groups__set_modules_path_dir(mg, path); ret = map_groups__set_modules_path_dir(mg, path);
if (ret < 0) if (ret < 0)
goto out; goto out;
@ -1788,9 +1786,6 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,
if (map == NULL) if (map == NULL)
continue; continue;
snprintf(path, sizeof(path), "%s/%s",
dir_name, dent->d_name);
long_name = strdup(path); long_name = strdup(path);
if (long_name == NULL) { if (long_name == NULL) {
ret = -1; ret = -1;
@ -2609,10 +2604,10 @@ int symbol__init(void)
symbol_conf.initialized = true; symbol_conf.initialized = true;
return 0; return 0;
out_free_dso_list:
strlist__delete(symbol_conf.dso_list);
out_free_comm_list: out_free_comm_list:
strlist__delete(symbol_conf.comm_list); strlist__delete(symbol_conf.comm_list);
out_free_dso_list:
strlist__delete(symbol_conf.dso_list);
return -1; return -1;
} }

View file

@ -1,5 +1,8 @@
/* /*
* GIT - The information manager from hell * usage.c
*
* Various reporting routines.
* Originally copied from GIT source.
* *
* Copyright (C) Linus Torvalds, 2005 * Copyright (C) Linus Torvalds, 2005
*/ */

View file

@ -32,6 +32,7 @@ void perf_read_values_destroy(struct perf_read_values *values)
for (i = 0; i < values->threads; i++) for (i = 0; i < values->threads; i++)
free(values->value[i]); free(values->value[i]);
free(values->value);
free(values->pid); free(values->pid);
free(values->tid); free(values->tid);
free(values->counterrawid); free(values->counterrawid);