Commit d1e169da 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

Includes smaller fixes and improvements plus the exclude_{host,guest} feature
test and fallback to handle older kernels.
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parents f8d98f10 808e1226
...@@ -52,11 +52,11 @@ OPTIONS ...@@ -52,11 +52,11 @@ OPTIONS
-p:: -p::
--pid=:: --pid=::
Record events on existing process ID. Record events on existing process ID (comma separated list).
-t:: -t::
--tid=:: --tid=::
Record events on existing thread ID. Record events on existing thread ID (comma separated list).
-u:: -u::
--uid=:: --uid=::
......
...@@ -35,11 +35,11 @@ OPTIONS ...@@ -35,11 +35,11 @@ OPTIONS
child tasks do not inherit counters child tasks do not inherit counters
-p:: -p::
--pid=<pid>:: --pid=<pid>::
stat events on existing process id stat events on existing process id (comma separated list)
-t:: -t::
--tid=<tid>:: --tid=<tid>::
stat events on existing thread id stat events on existing thread id (comma separated list)
-a:: -a::
......
...@@ -72,11 +72,11 @@ Default is to monitor all CPUS. ...@@ -72,11 +72,11 @@ Default is to monitor all CPUS.
-p <pid>:: -p <pid>::
--pid=<pid>:: --pid=<pid>::
Profile events on existing Process ID. Profile events on existing Process ID (comma separated list).
-t <tid>:: -t <tid>::
--tid=<tid>:: --tid=<tid>::
Profile events on existing thread ID. Profile events on existing thread ID (comma separated list).
-u:: -u::
--uid=:: --uid=::
......
...@@ -9,6 +9,7 @@ lib/rbtree.c ...@@ -9,6 +9,7 @@ lib/rbtree.c
include/linux/swab.h include/linux/swab.h
arch/*/include/asm/unistd*.h arch/*/include/asm/unistd*.h
arch/*/lib/memcpy*.S arch/*/lib/memcpy*.S
arch/*/lib/memset*.S
include/linux/poison.h include/linux/poison.h
include/linux/magic.h include/linux/magic.h
include/linux/hw_breakpoint.h include/linux/hw_breakpoint.h
...@@ -183,7 +183,10 @@ SCRIPT_SH += perf-archive.sh ...@@ -183,7 +183,10 @@ SCRIPT_SH += perf-archive.sh
grep-libs = $(filter -l%,$(1)) grep-libs = $(filter -l%,$(1))
strip-libs = $(filter-out -l%,$(1)) strip-libs = $(filter-out -l%,$(1))
$(OUTPUT)python/perf.so: $(PYRF_OBJS) PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py
$(OUTPUT)python/perf.so: $(PYRF_OBJS) $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
$(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \ $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \
--quiet build_ext; \ --quiet build_ext; \
mkdir -p $(OUTPUT)python && \ mkdir -p $(OUTPUT)python && \
...@@ -256,6 +259,7 @@ LIB_H += util/callchain.h ...@@ -256,6 +259,7 @@ LIB_H += util/callchain.h
LIB_H += util/build-id.h LIB_H += util/build-id.h
LIB_H += util/debug.h LIB_H += util/debug.h
LIB_H += util/debugfs.h LIB_H += util/debugfs.h
LIB_H += util/sysfs.h
LIB_H += util/event.h LIB_H += util/event.h
LIB_H += util/evsel.h LIB_H += util/evsel.h
LIB_H += util/evlist.h LIB_H += util/evlist.h
...@@ -302,6 +306,7 @@ LIB_OBJS += $(OUTPUT)util/build-id.o ...@@ -302,6 +306,7 @@ LIB_OBJS += $(OUTPUT)util/build-id.o
LIB_OBJS += $(OUTPUT)util/config.o LIB_OBJS += $(OUTPUT)util/config.o
LIB_OBJS += $(OUTPUT)util/ctype.o LIB_OBJS += $(OUTPUT)util/ctype.o
LIB_OBJS += $(OUTPUT)util/debugfs.o LIB_OBJS += $(OUTPUT)util/debugfs.o
LIB_OBJS += $(OUTPUT)util/sysfs.o
LIB_OBJS += $(OUTPUT)util/environment.o LIB_OBJS += $(OUTPUT)util/environment.o
LIB_OBJS += $(OUTPUT)util/event.o LIB_OBJS += $(OUTPUT)util/event.o
LIB_OBJS += $(OUTPUT)util/evlist.o LIB_OBJS += $(OUTPUT)util/evlist.o
......
...@@ -205,8 +205,11 @@ static void perf_record__open(struct perf_record *rec) ...@@ -205,8 +205,11 @@ static void perf_record__open(struct perf_record *rec)
if (opts->group && pos != first) if (opts->group && pos != first)
group_fd = first->fd; group_fd = first->fd;
fallback_missing_features:
if (opts->exclude_guest_missing)
attr->exclude_guest = attr->exclude_host = 0;
retry_sample_id: retry_sample_id:
attr->sample_id_all = opts->sample_id_all_avail ? 1 : 0; attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1;
try_again: try_again:
if (perf_evsel__open(pos, evlist->cpus, evlist->threads, if (perf_evsel__open(pos, evlist->cpus, evlist->threads,
opts->group, group_fd) < 0) { opts->group, group_fd) < 0) {
...@@ -218,16 +221,24 @@ static void perf_record__open(struct perf_record *rec) ...@@ -218,16 +221,24 @@ static void perf_record__open(struct perf_record *rec)
} else if (err == ENODEV && opts->cpu_list) { } else if (err == ENODEV && opts->cpu_list) {
die("No such device - did you specify" die("No such device - did you specify"
" an out-of-range profile CPU?\n"); " an out-of-range profile CPU?\n");
} else if (err == EINVAL && opts->sample_id_all_avail) { } else if (err == EINVAL) {
if (!opts->exclude_guest_missing &&
(attr->exclude_guest || attr->exclude_host)) {
pr_debug("Old kernel, cannot exclude "
"guest or host samples.\n");
opts->exclude_guest_missing = true;
goto fallback_missing_features;
} else if (!opts->sample_id_all_missing) {
/* /*
* Old kernel, no attr->sample_id_type_all field * Old kernel, no attr->sample_id_type_all field
*/ */
opts->sample_id_all_avail = false; opts->sample_id_all_missing = true;
if (!opts->sample_time && !opts->raw_samples && !time_needed) if (!opts->sample_time && !opts->raw_samples && !time_needed)
attr->sample_type &= ~PERF_SAMPLE_TIME; attr->sample_type &= ~PERF_SAMPLE_TIME;
goto retry_sample_id; goto retry_sample_id;
} }
}
/* /*
* If it's cycles then fall back to hrtimer * If it's cycles then fall back to hrtimer
...@@ -494,9 +505,9 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) ...@@ -494,9 +505,9 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
return err; return err;
} }
if (!!rec->no_buildid if (!rec->no_buildid
&& !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) { && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
pr_err("Couldn't generating buildids. " pr_err("Couldn't generate buildids. "
"Use --no-buildid to profile anyway.\n"); "Use --no-buildid to profile anyway.\n");
return -1; return -1;
} }
...@@ -645,13 +656,10 @@ static const char * const record_usage[] = { ...@@ -645,13 +656,10 @@ static const char * const record_usage[] = {
*/ */
static struct perf_record record = { static struct perf_record record = {
.opts = { .opts = {
.target_pid = -1,
.target_tid = -1,
.mmap_pages = UINT_MAX, .mmap_pages = UINT_MAX,
.user_freq = UINT_MAX, .user_freq = UINT_MAX,
.user_interval = ULLONG_MAX, .user_interval = ULLONG_MAX,
.freq = 1000, .freq = 1000,
.sample_id_all_avail = true,
}, },
.write_mode = WRITE_FORCE, .write_mode = WRITE_FORCE,
.file_new = true, .file_new = true,
...@@ -670,9 +678,9 @@ const struct option record_options[] = { ...@@ -670,9 +678,9 @@ const struct option record_options[] = {
parse_events_option), parse_events_option),
OPT_CALLBACK(0, "filter", &record.evlist, "filter", OPT_CALLBACK(0, "filter", &record.evlist, "filter",
"event filter", parse_filter), "event filter", parse_filter),
OPT_INTEGER('p', "pid", &record.opts.target_pid, OPT_STRING('p', "pid", &record.opts.target_pid, "pid",
"record events on existing process id"), "record events on existing process id"),
OPT_INTEGER('t', "tid", &record.opts.target_tid, OPT_STRING('t', "tid", &record.opts.target_tid, "tid",
"record events on existing thread id"), "record events on existing thread id"),
OPT_INTEGER('r', "realtime", &record.realtime_prio, OPT_INTEGER('r', "realtime", &record.realtime_prio,
"collect data with this RT SCHED_FIFO priority"), "collect data with this RT SCHED_FIFO priority"),
...@@ -739,7 +747,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) ...@@ -739,7 +747,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
argc = parse_options(argc, argv, record_options, record_usage, argc = parse_options(argc, argv, record_options, record_usage,
PARSE_OPT_STOP_AT_NON_OPTION); PARSE_OPT_STOP_AT_NON_OPTION);
if (!argc && rec->opts.target_pid == -1 && rec->opts.target_tid == -1 && if (!argc && !rec->opts.target_pid && !rec->opts.target_tid &&
!rec->opts.system_wide && !rec->opts.cpu_list && !rec->uid_str) !rec->opts.system_wide && !rec->opts.cpu_list && !rec->uid_str)
usage_with_options(record_usage, record_options); usage_with_options(record_usage, record_options);
...@@ -785,7 +793,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) ...@@ -785,7 +793,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
if (rec->uid_str != NULL && rec->opts.uid == UINT_MAX - 1) if (rec->uid_str != NULL && rec->opts.uid == UINT_MAX - 1)
goto out_free_fd; goto out_free_fd;
if (rec->opts.target_pid != -1) if (rec->opts.target_pid)
rec->opts.target_tid = rec->opts.target_pid; rec->opts.target_tid = rec->opts.target_pid;
if (perf_evlist__create_maps(evsel_list, rec->opts.target_pid, if (perf_evlist__create_maps(evsel_list, rec->opts.target_pid,
......
...@@ -182,8 +182,8 @@ static int run_count = 1; ...@@ -182,8 +182,8 @@ static int run_count = 1;
static bool no_inherit = false; static bool no_inherit = false;
static bool scale = true; static bool scale = true;
static bool no_aggr = false; static bool no_aggr = false;
static pid_t target_pid = -1; static const char *target_pid;
static pid_t target_tid = -1; static const char *target_tid;
static pid_t child_pid = -1; static pid_t child_pid = -1;
static bool null_run = false; static bool null_run = false;
static int detailed_run = 0; static int detailed_run = 0;
...@@ -296,7 +296,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel, ...@@ -296,7 +296,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel,
if (system_wide) if (system_wide)
return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, return perf_evsel__open_per_cpu(evsel, evsel_list->cpus,
group, group_fd); group, group_fd);
if (target_pid == -1 && target_tid == -1) { if (!target_pid && !target_tid) {
attr->disabled = 1; attr->disabled = 1;
attr->enable_on_exec = 1; attr->enable_on_exec = 1;
} }
...@@ -446,7 +446,7 @@ static int run_perf_stat(int argc __used, const char **argv) ...@@ -446,7 +446,7 @@ static int run_perf_stat(int argc __used, const char **argv)
exit(-1); exit(-1);
} }
if (target_tid == -1 && target_pid == -1 && !system_wide) if (!target_tid && !target_pid && !system_wide)
evsel_list->threads->map[0] = child_pid; evsel_list->threads->map[0] = child_pid;
/* /*
...@@ -968,14 +968,14 @@ static void print_stat(int argc, const char **argv) ...@@ -968,14 +968,14 @@ static void print_stat(int argc, const char **argv)
if (!csv_output) { if (!csv_output) {
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, " Performance counter stats for "); fprintf(output, " Performance counter stats for ");
if(target_pid == -1 && target_tid == -1) { if (!target_pid && !target_tid) {
fprintf(output, "\'%s", argv[0]); fprintf(output, "\'%s", argv[0]);
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
fprintf(output, " %s", argv[i]); fprintf(output, " %s", argv[i]);
} else if (target_pid != -1) } else if (target_pid)
fprintf(output, "process id \'%d", target_pid); fprintf(output, "process id \'%s", target_pid);
else else
fprintf(output, "thread id \'%d", target_tid); fprintf(output, "thread id \'%s", target_tid);
fprintf(output, "\'"); fprintf(output, "\'");
if (run_count > 1) if (run_count > 1)
...@@ -1049,9 +1049,9 @@ static const struct option options[] = { ...@@ -1049,9 +1049,9 @@ static const struct option options[] = {
"event filter", parse_filter), "event filter", parse_filter),
OPT_BOOLEAN('i', "no-inherit", &no_inherit, OPT_BOOLEAN('i', "no-inherit", &no_inherit,
"child tasks do not inherit counters"), "child tasks do not inherit counters"),
OPT_INTEGER('p', "pid", &target_pid, OPT_STRING('p', "pid", &target_pid, "pid",
"stat events on existing process id"), "stat events on existing process id"),
OPT_INTEGER('t', "tid", &target_tid, OPT_STRING('t', "tid", &target_tid, "tid",
"stat events on existing thread id"), "stat events on existing thread id"),
OPT_BOOLEAN('a', "all-cpus", &system_wide, OPT_BOOLEAN('a', "all-cpus", &system_wide,
"system-wide collection from all CPUs"), "system-wide collection from all CPUs"),
...@@ -1190,7 +1190,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) ...@@ -1190,7 +1190,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
} else if (big_num_opt == 0) /* User passed --no-big-num */ } else if (big_num_opt == 0) /* User passed --no-big-num */
big_num = false; big_num = false;
if (!argc && target_pid == -1 && target_tid == -1) if (!argc && !target_pid && !target_tid)
usage_with_options(stat_usage, options); usage_with_options(stat_usage, options);
if (run_count <= 0) if (run_count <= 0)
usage_with_options(stat_usage, options); usage_with_options(stat_usage, options);
...@@ -1206,10 +1206,11 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) ...@@ -1206,10 +1206,11 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
if (add_default_attributes()) if (add_default_attributes())
goto out; goto out;
if (target_pid != -1) if (target_pid)
target_tid = target_pid; target_tid = target_pid;
evsel_list->threads = thread_map__new(target_pid, target_tid, UINT_MAX); evsel_list->threads = thread_map__new_str(target_pid,
target_tid, UINT_MAX);
if (evsel_list->threads == NULL) { if (evsel_list->threads == NULL) {
pr_err("Problems finding threads of monitor\n"); pr_err("Problems finding threads of monitor\n");
usage_with_options(stat_usage, options); usage_with_options(stat_usage, options);
......
...@@ -1010,12 +1010,9 @@ static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t **maskp, ...@@ -1010,12 +1010,9 @@ static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t **maskp,
static int test__PERF_RECORD(void) static int test__PERF_RECORD(void)
{ {
struct perf_record_opts opts = { struct perf_record_opts opts = {
.target_pid = -1,
.target_tid = -1,
.no_delay = true, .no_delay = true,
.freq = 10, .freq = 10,
.mmap_pages = 256, .mmap_pages = 256,
.sample_id_all_avail = true,
}; };
cpu_set_t *cpu_mask = NULL; cpu_set_t *cpu_mask = NULL;
size_t cpu_mask_size = 0; size_t cpu_mask_size = 0;
......
...@@ -677,6 +677,12 @@ static void perf_event__process_sample(struct perf_tool *tool, ...@@ -677,6 +677,12 @@ static void perf_event__process_sample(struct perf_tool *tool,
return; return;
} }
if (!machine) {
pr_err("%u unprocessable samples recorded.",
top->session->hists.stats.nr_unprocessable_samples++);
return;
}
if (event->header.misc & PERF_RECORD_MISC_EXACT_IP) if (event->header.misc & PERF_RECORD_MISC_EXACT_IP)
top->exact_samples++; top->exact_samples++;
...@@ -866,8 +872,11 @@ static void perf_top__start_counters(struct perf_top *top) ...@@ -866,8 +872,11 @@ static void perf_top__start_counters(struct perf_top *top)
attr->mmap = 1; attr->mmap = 1;
attr->comm = 1; attr->comm = 1;
attr->inherit = top->inherit; attr->inherit = top->inherit;
fallback_missing_features:
if (top->exclude_guest_missing)
attr->exclude_guest = attr->exclude_host = 0;
retry_sample_id: retry_sample_id:
attr->sample_id_all = top->sample_id_all_avail ? 1 : 0; attr->sample_id_all = top->sample_id_all_missing ? 0 : 1;
try_again: try_again:
if (perf_evsel__open(counter, top->evlist->cpus, if (perf_evsel__open(counter, top->evlist->cpus,
top->evlist->threads, top->group, top->evlist->threads, top->group,
...@@ -877,13 +886,21 @@ static void perf_top__start_counters(struct perf_top *top) ...@@ -877,13 +886,21 @@ static void perf_top__start_counters(struct perf_top *top)
if (err == EPERM || err == EACCES) { if (err == EPERM || err == EACCES) {
ui__error_paranoid(); ui__error_paranoid();
goto out_err; goto out_err;
} else if (err == EINVAL && top->sample_id_all_avail) { } else if (err == EINVAL) {
if (!top->exclude_guest_missing &&
(attr->exclude_guest || attr->exclude_host)) {
pr_debug("Old kernel, cannot exclude "
"guest or host samples.\n");
top->exclude_guest_missing = true;
goto fallback_missing_features;
} else if (!top->sample_id_all_missing) {
/* /*
* Old kernel, no attr->sample_id_type_all field * Old kernel, no attr->sample_id_type_all field
*/ */
top->sample_id_all_avail = false; top->sample_id_all_missing = true;
goto retry_sample_id; goto retry_sample_id;
} }
}
/* /*
* If it's cycles then fall back to hrtimer * If it's cycles then fall back to hrtimer
* based cpu-clock-tick sw counter, which * based cpu-clock-tick sw counter, which
...@@ -965,7 +982,7 @@ static int __cmd_top(struct perf_top *top) ...@@ -965,7 +982,7 @@ static int __cmd_top(struct perf_top *top)
if (ret) if (ret)
goto out_delete; goto out_delete;
if (top->target_tid != -1 || top->uid != UINT_MAX) if (top->target_tid || top->uid != UINT_MAX)
perf_event__synthesize_thread_map(&top->tool, top->evlist->threads, perf_event__synthesize_thread_map(&top->tool, top->evlist->threads,
perf_event__process, perf_event__process,
&top->session->host_machine); &top->session->host_machine);
...@@ -1103,11 +1120,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) ...@@ -1103,11 +1120,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
struct perf_top top = { struct perf_top top = {
.count_filter = 5, .count_filter = 5,
.delay_secs = 2, .delay_secs = 2,
.target_pid = -1,
.target_tid = -1,
.uid = UINT_MAX, .uid = UINT_MAX,
.freq = 1000, /* 1 KHz */ .freq = 1000, /* 1 KHz */
.sample_id_all_avail = true,
.mmap_pages = 128, .mmap_pages = 128,
.sym_pcnt_filter = 5, .sym_pcnt_filter = 5,
}; };
...@@ -1118,9 +1132,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) ...@@ -1118,9 +1132,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
parse_events_option), parse_events_option),
OPT_INTEGER('c', "count", &top.default_interval, OPT_INTEGER('c', "count", &top.default_interval,
"event period to sample"), "event period to sample"),
OPT_INTEGER('p', "pid", &top.target_pid, OPT_STRING('p', "pid", &top.target_pid, "pid",
"profile events on existing process id"), "profile events on existing process id"),
OPT_INTEGER('t', "tid", &top.target_tid, OPT_STRING('t', "tid", &top.target_tid, "tid",
"profile events on existing thread id"), "profile events on existing thread id"),
OPT_BOOLEAN('a', "all-cpus", &top.system_wide, OPT_BOOLEAN('a', "all-cpus", &top.system_wide,
"system-wide collection from all CPUs"), "system-wide collection from all CPUs"),
...@@ -1210,13 +1224,13 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) ...@@ -1210,13 +1224,13 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
goto out_delete_evlist; goto out_delete_evlist;
/* CPU and PID are mutually exclusive */ /* CPU and PID are mutually exclusive */
if (top.target_tid > 0 && top.cpu_list) { if (top.target_tid && top.cpu_list) {
printf("WARNING: PID switch overriding CPU\n"); printf("WARNING: PID switch overriding CPU\n");
sleep(1); sleep(1);
top.cpu_list = NULL; top.cpu_list = NULL;
} }
if (top.target_pid != -1) if (top.target_pid)
top.target_tid = top.target_pid; top.target_tid = top.target_pid;
if (perf_evlist__create_maps(top.evlist, top.target_pid, if (perf_evlist__create_maps(top.evlist, top.target_pid,
......
...@@ -167,7 +167,6 @@ sys_perf_event_open(struct perf_event_attr *attr, ...@@ -167,7 +167,6 @@ sys_perf_event_open(struct perf_event_attr *attr,
pid_t pid, int cpu, int group_fd, pid_t pid, int cpu, int group_fd,
unsigned long flags) unsigned long flags)
{ {
attr->size = sizeof(*attr);
return syscall(__NR_perf_event_open, attr, pid, cpu, return syscall(__NR_perf_event_open, attr, pid, cpu,
group_fd, flags); group_fd, flags);
} }
...@@ -186,8 +185,8 @@ extern const char perf_version_string[]; ...@@ -186,8 +185,8 @@ extern const char perf_version_string[];
void pthread__unblock_sigwinch(void); void pthread__unblock_sigwinch(void);
struct perf_record_opts { struct perf_record_opts {
pid_t target_pid; const char *target_pid;
pid_t target_tid; const char *target_tid;
uid_t uid; uid_t uid;
bool call_graph; bool call_graph;
bool group; bool group;
...@@ -199,7 +198,8 @@ struct perf_record_opts { ...@@ -199,7 +198,8 @@ struct perf_record_opts {
bool raw_samples; bool raw_samples;
bool sample_address; bool sample_address;
bool sample_time; bool sample_time;
bool sample_id_all_avail; bool sample_id_all_missing;
bool exclude_guest_missing;
bool system_wide; bool system_wide;
bool period; bool period;
unsigned int freq; unsigned int freq;
......
...@@ -19,3 +19,13 @@ int __bitmap_weight(const unsigned long *bitmap, int bits) ...@@ -19,3 +19,13 @@ int __bitmap_weight(const unsigned long *bitmap, int bits)
return w; return w;
} }
void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits)
{
int k;
int nr = BITS_TO_LONGS(bits);
for (k = 0; k < nr; k++)
dst[k] = bitmap1[k] | bitmap2[k];
}
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* No surprises, and works with signed and unsigned chars. * No surprises, and works with signed and unsigned chars.
*/ */
#include "cache.h" #include "util.h"
enum { enum {
S = GIT_SPACE, S = GIT_SPACE,
......
...@@ -15,32 +15,6 @@ static const char *debugfs_known_mountpoints[] = { ...@@ -15,32 +15,6 @@ static const char *debugfs_known_mountpoints[] = {
0, 0,
}; };
/* use this to force a umount */
void debugfs_force_cleanup(void)
{
debugfs_find_mountpoint();
debugfs_premounted = 0;
debugfs_umount();
}
/* construct a full path to a debugfs element */
int debugfs_make_path(const char *element, char *buffer, int size)
{
int len;
if (strlen(debugfs_mountpoint) == 0) {
buffer[0] = '\0';
return -1;
}
len = strlen(debugfs_mountpoint) + strlen(element) + 1;
if (len >= size)
return len+1;
snprintf(buffer, size-1, "%s/%s", debugfs_mountpoint, element);
return 0;
}
static int debugfs_found; static int debugfs_found;
/* find the path to the mounted debugfs */ /* find the path to the mounted debugfs */
...@@ -97,17 +71,6 @@ int debugfs_valid_mountpoint(const char *debugfs) ...@@ -97,17 +71,6 @@ int debugfs_valid_mountpoint(const char *debugfs)
return 0; return 0;
} }
int debugfs_valid_entry(const char *path)
{
struct stat st;
if (stat(path, &st))
return -errno;
return 0;
}
static void debugfs_set_tracing_events_path(const char *mountpoint) static void debugfs_set_tracing_events_path(const char *mountpoint)
{ {
snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s", snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s",
...@@ -149,107 +112,3 @@ void debugfs_set_path(const char *mountpoint) ...@@ -149,107 +112,3 @@ void debugfs_set_path(const char *mountpoint)
snprintf(debugfs_mountpoint, sizeof(debugfs_mountpoint), "%s", mountpoint); snprintf(debugfs_mountpoint, sizeof(debugfs_mountpoint), "%s", mountpoint);
debugfs_set_tracing_events_path(mountpoint); debugfs_set_tracing_events_path(mountpoint);
} }
/* umount the debugfs */
int debugfs_umount(void)
{
char umountcmd[128];
int ret;
/* if it was already mounted, leave it */
if (debugfs_premounted)
return 0;
/* make sure it's a valid mount point */
ret = debugfs_valid_mountpoint(debugfs_mountpoint);
if (ret)
return ret;
snprintf(umountcmd, sizeof(umountcmd),
"/bin/umount %s", debugfs_mountpoint);
return system(umountcmd);
}
int debugfs_write(const char *entry, const char *value)
{
char path[PATH_MAX + 1];
int ret, count;
int fd;
/* construct the path */
snprintf(path, sizeof(path), "%s/%s", debugfs_mountpoint, entry);
/* verify that it exists */
ret = debugfs_valid_entry(path);
if (ret)
return ret;
/* get how many chars we're going to write */
count = strlen(value);
/* open the debugfs entry */
fd = open(path, O_RDWR);
if (fd < 0)
return -errno;
while (count > 0) {
/* write it */
ret = write(fd, value, count);
if (ret <= 0) {
if (ret == EAGAIN)
continue;
close(fd);
return -errno;
}
count -= ret;
}
/* close it */
close(fd);
/* return success */
return 0;
}
/*
* read a debugfs entry
* returns the number of chars read or a negative errno
*/
int debugfs_read(const char *entry, char *buffer, size_t size)
{
char path[PATH_MAX + 1];
int ret;
int fd;
/* construct the path */
snprintf(path, sizeof(path), "%s/%s", debugfs_mountpoint, entry);
/* verify that it exists */
ret = debugfs_valid_entry(path);
if (ret)
return ret;
/* open the debugfs entry */
fd = open(path, O_RDONLY);
if (fd < 0)
return -errno;
do {
/* read it */
ret = read(fd, buffer, size);
if (ret == 0) {
close(fd);
return EOF;
}
} while (ret < 0 && errno == EAGAIN);
/* close it */
close(fd);
/* make *sure* there's a null character at the end */
buffer[ret] = '\0';
/* return the number of chars read */
return ret;
}
...@@ -3,14 +3,8 @@ ...@@ -3,14 +3,8 @@
const char *debugfs_find_mountpoint(void); const char *debugfs_find_mountpoint(void);
int debugfs_valid_mountpoint(const char *debugfs); int debugfs_valid_mountpoint(const char *debugfs);
int debugfs_valid_entry(const char *path);
char *debugfs_mount(const char *mountpoint); char *debugfs_mount(const char *mountpoint);
int debugfs_umount(void);
void debugfs_set_path(const char *mountpoint); void debugfs_set_path(const char *mountpoint);
int debugfs_write(const char *entry, const char *value);
int debugfs_read(const char *entry, char *buffer, size_t size);
void debugfs_force_cleanup(void);
int debugfs_make_path(const char *element, char *buffer, int size);
extern char debugfs_mountpoint[]; extern char debugfs_mountpoint[];
extern char tracing_events_path[]; extern char tracing_events_path[];
......
...@@ -593,15 +593,15 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, ...@@ -593,15 +593,15 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
return perf_evlist__mmap_per_cpu(evlist, prot, mask); return perf_evlist__mmap_per_cpu(evlist, prot, mask);
} }
int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, int perf_evlist__create_maps(struct perf_evlist *evlist, const char *target_pid,
pid_t target_tid, uid_t uid, const char *cpu_list) const char *target_tid, uid_t uid, const char *cpu_list)
{ {
evlist->threads = thread_map__new(target_pid, target_tid, uid); evlist->threads = thread_map__new_str(target_pid, target_tid, uid);
if (evlist->threads == NULL) if (evlist->threads == NULL)
return -1; return -1;
if (uid != UINT_MAX || (cpu_list == NULL && target_tid != -1)) if (uid != UINT_MAX || (cpu_list == NULL && target_tid))
evlist->cpus = cpu_map__dummy_new(); evlist->cpus = cpu_map__dummy_new();
else else
evlist->cpus = cpu_map__new(cpu_list); evlist->cpus = cpu_map__new(cpu_list);
...@@ -820,7 +820,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, ...@@ -820,7 +820,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
exit(-1); exit(-1);
} }
if (!opts->system_wide && opts->target_tid == -1 && opts->target_pid == -1) if (!opts->system_wide && !opts->target_tid && !opts->target_pid)
evlist->threads->map[0] = evlist->workload.pid; evlist->threads->map[0] = evlist->workload.pid;
close(child_ready_pipe[1]); close(child_ready_pipe[1]);
......
...@@ -106,8 +106,8 @@ static inline void perf_evlist__set_maps(struct perf_evlist *evlist, ...@@ -106,8 +106,8 @@ static inline void perf_evlist__set_maps(struct perf_evlist *evlist,
evlist->threads = threads; evlist->threads = threads;
} }
int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, int perf_evlist__create_maps(struct perf_evlist *evlist, const char *target_pid,
pid_t tid, uid_t uid, const char *cpu_list); const char *tid, uid_t uid, const char *cpu_list);
void perf_evlist__delete_maps(struct perf_evlist *evlist); void perf_evlist__delete_maps(struct perf_evlist *evlist);
int perf_evlist__set_filters(struct perf_evlist *evlist); int perf_evlist__set_filters(struct perf_evlist *evlist);
......
...@@ -68,7 +68,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts) ...@@ -68,7 +68,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts)
struct perf_event_attr *attr = &evsel->attr; struct perf_event_attr *attr = &evsel->attr;
int track = !evsel->idx; /* only the first counter needs these */ int track = !evsel->idx; /* only the first counter needs these */
attr->sample_id_all = opts->sample_id_all_avail ? 1 : 0; attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1;
attr->inherit = !opts->no_inherit; attr->inherit = !opts->no_inherit;
attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
PERF_FORMAT_TOTAL_TIME_RUNNING | PERF_FORMAT_TOTAL_TIME_RUNNING |
...@@ -111,7 +111,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts) ...@@ -111,7 +111,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts)
if (opts->period) if (opts->period)
attr->sample_type |= PERF_SAMPLE_PERIOD; attr->sample_type |= PERF_SAMPLE_PERIOD;
if (opts->sample_id_all_avail && if (!opts->sample_id_all_missing &&
(opts->sample_time || opts->system_wide || (opts->sample_time || opts->system_wide ||
!opts->no_inherit || opts->cpu_list)) !opts->no_inherit || opts->cpu_list))
attr->sample_type |= PERF_SAMPLE_TIME; attr->sample_type |= PERF_SAMPLE_TIME;
...@@ -130,7 +130,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts) ...@@ -130,7 +130,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts)
attr->mmap = track; attr->mmap = track;
attr->comm = track; attr->comm = track;
if (opts->target_pid == -1 && opts->target_tid == -1 && !opts->system_wide) { if (!opts->target_pid && !opts->target_tid && !opts->system_wide) {
attr->disabled = 1; attr->disabled = 1;
attr->enable_on_exec = 1; attr->enable_on_exec = 1;
} }
......
This diff is collapsed.
...@@ -32,6 +32,7 @@ struct events_stats { ...@@ -32,6 +32,7 @@ struct events_stats {
u32 nr_unknown_events; u32 nr_unknown_events;
u32 nr_invalid_chains; u32 nr_invalid_chains;
u32 nr_unknown_id; u32 nr_unknown_id;
u32 nr_unprocessable_samples;
}; };
enum hist_column { enum hist_column {
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include <linux/bitops.h> #include <linux/bitops.h>
int __bitmap_weight(const unsigned long *bitmap, int bits); int __bitmap_weight(const unsigned long *bitmap, int bits);
void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits);
#define BITMAP_LAST_WORD_MASK(nbits) \ #define BITMAP_LAST_WORD_MASK(nbits) \
( \ ( \
...@@ -32,4 +34,13 @@ static inline int bitmap_weight(const unsigned long *src, int nbits) ...@@ -32,4 +34,13 @@ static inline int bitmap_weight(const unsigned long *src, int nbits)
return __bitmap_weight(src, nbits); return __bitmap_weight(src, nbits);
} }
static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
const unsigned long *src2, int nbits)
{
if (small_const_nbits(nbits))
*dst = *src1 | *src2;
else
__bitmap_or(dst, src1, src2, nbits);
}
#endif /* _PERF_BITOPS_H */ #endif /* _PERF_BITOPS_H */
#
# List of files needed by perf python extention
#
# Each source file must be placed on its own line so that it can be
# processed by Makefile and util/setup.py accordingly.
#
util/python.c
util/ctype.c
util/evlist.c
util/evsel.c
util/cpumap.c
util/thread_map.c
util/util.c
util/xyarray.c
util/cgroup.c
util/debugfs.c
util/strlist.c
../../lib/rbtree.c
...@@ -796,6 +796,10 @@ static int perf_session_deliver_event(struct perf_session *session, ...@@ -796,6 +796,10 @@ static int perf_session_deliver_event(struct perf_session *session,
++session->hists.stats.nr_unknown_id; ++session->hists.stats.nr_unknown_id;
return -1; return -1;
} }
if (machine == NULL) {
++session->hists.stats.nr_unprocessable_samples;
return -1;
}
return tool->sample(tool, event, sample, evsel, machine); return tool->sample(tool, event, sample, evsel, machine);
case PERF_RECORD_MMAP: case PERF_RECORD_MMAP:
return tool->mmap(tool, event, sample, machine); return tool->mmap(tool, event, sample, machine);
...@@ -964,6 +968,12 @@ static void perf_session__warn_about_errors(const struct perf_session *session, ...@@ -964,6 +968,12 @@ static void perf_session__warn_about_errors(const struct perf_session *session,
session->hists.stats.nr_invalid_chains, session->hists.stats.nr_invalid_chains,
session->hists.stats.nr_events[PERF_RECORD_SAMPLE]); session->hists.stats.nr_events[PERF_RECORD_SAMPLE]);
} }
if (session->hists.stats.nr_unprocessable_samples != 0) {
ui__warning("%u unprocessable samples recorded.\n"
"Do you have a KVM guest running and not using 'perf kvm'?\n",
session->hists.stats.nr_unprocessable_samples);
}
} }
#define session_done() (*(volatile int *)(&session_done)) #define session_done() (*(volatile int *)(&session_done))
......
...@@ -24,11 +24,11 @@ cflags += getenv('CFLAGS', '').split() ...@@ -24,11 +24,11 @@ cflags += getenv('CFLAGS', '').split()
build_lib = getenv('PYTHON_EXTBUILD_LIB') build_lib = getenv('PYTHON_EXTBUILD_LIB')
build_tmp = getenv('PYTHON_EXTBUILD_TMP') build_tmp = getenv('PYTHON_EXTBUILD_TMP')
ext_sources = [f.strip() for f in file('util/python-ext-sources')
if len(f.strip()) > 0 and f[0] != '#']
perf = Extension('perf', perf = Extension('perf',
sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c', sources = ext_sources,
'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c',
'util/util.c', 'util/xyarray.c', 'util/cgroup.c',
'util/debugfs.c'],
include_dirs = ['util/include'], include_dirs = ['util/include'],
extra_compile_args = cflags, extra_compile_args = cflags,
) )
......
#include <ctype.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <libgen.h> #include <libgen.h>
...@@ -12,6 +11,7 @@ ...@@ -12,6 +11,7 @@
#include <unistd.h> #include <unistd.h>
#include <inttypes.h> #include <inttypes.h>
#include "build-id.h" #include "build-id.h"
#include "util.h"
#include "debug.h" #include "debug.h"
#include "symbol.h" #include "symbol.h"
#include "strlist.h" #include "strlist.h"
......
#include "util.h"
#include "sysfs.h"
static const char * const sysfs_known_mountpoints[] = {
"/sys",
0,
};
static int sysfs_found;
char sysfs_mountpoint[PATH_MAX];
static int sysfs_valid_mountpoint(const char *sysfs)
{
struct statfs st_fs;
if (statfs(sysfs, &st_fs) < 0)
return -ENOENT;
else if (st_fs.f_type != (long) SYSFS_MAGIC)
return -ENOENT;
return 0;
}
const char *sysfs_find_mountpoint(void)
{
const char * const *ptr;
char type[100];
FILE *fp;
if (sysfs_found)
return (const char *) sysfs_mountpoint;
ptr = sysfs_known_mountpoints;
while (*ptr) {
if (sysfs_valid_mountpoint(*ptr) == 0) {
sysfs_found = 1;
strcpy(sysfs_mountpoint, *ptr);
return sysfs_mountpoint;
}
ptr++;
}
/* give up and parse /proc/mounts */
fp = fopen("/proc/mounts", "r");
if (fp == NULL)
return NULL;
while (!sysfs_found &&
fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
sysfs_mountpoint, type) == 2) {
if (strcmp(type, "sysfs") == 0)
sysfs_found = 1;
}
fclose(fp);
return sysfs_found ? sysfs_mountpoint : NULL;
}
#ifndef __SYSFS_H__
#define __SYSFS_H__
const char *sysfs_find_mountpoint(void);
#endif /* __DEBUGFS_H__ */
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include "strlist.h"
#include <string.h>
#include "thread_map.h" #include "thread_map.h"
/* Skip "." and ".." directories */ /* Skip "." and ".." directories */
...@@ -152,6 +154,132 @@ struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid) ...@@ -152,6 +154,132 @@ struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid)
return thread_map__new_by_tid(tid); return thread_map__new_by_tid(tid);
} }
static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
{
struct thread_map *threads = NULL, *nt;
char name[256];
int items, total_tasks = 0;
struct dirent **namelist = NULL;
int i, j = 0;
pid_t pid, prev_pid = INT_MAX;
char *end_ptr;
struct str_node *pos;
struct strlist *slist = strlist__new(false, pid_str);
if (!slist)
return NULL;
strlist__for_each(pos, slist) {
pid = strtol(pos->s, &end_ptr, 10);
if (pid == INT_MIN || pid == INT_MAX ||
(*end_ptr != '\0' && *end_ptr != ','))
goto out_free_threads;
if (pid == prev_pid)
continue;
sprintf(name, "/proc/%d/task", pid);
items = scandir(name, &namelist, filter, NULL);
if (items <= 0)
goto out_free_threads;
total_tasks += items;
nt = realloc(threads, (sizeof(*threads) +
sizeof(pid_t) * total_tasks));
if (nt == NULL)
goto out_free_threads;
threads = nt;
if (threads) {
for (i = 0; i < items; i++)
threads->map[j++] = atoi(namelist[i]->d_name);
threads->nr = total_tasks;
}
for (i = 0; i < items; i++)
free(namelist[i]);
free(namelist);
if (!threads)
break;
}
out:
strlist__delete(slist);
return threads;
out_free_threads:
free(threads);
threads = NULL;
goto out;
}
static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
{
struct thread_map *threads = NULL, *nt;
int ntasks = 0;
pid_t tid, prev_tid = INT_MAX;
char *end_ptr;
struct str_node *pos;
struct strlist *slist;
/* perf-stat expects threads to be generated even if tid not given */
if (!tid_str) {
threads = malloc(sizeof(*threads) + sizeof(pid_t));
if (threads != NULL) {
threads->map[1] = -1;
threads->nr = 1;
}
return threads;
}
slist = strlist__new(false, tid_str);
if (!slist)
return NULL;
strlist__for_each(pos, slist) {
tid = strtol(pos->s, &end_ptr, 10);
if (tid == INT_MIN || tid == INT_MAX ||
(*end_ptr != '\0' && *end_ptr != ','))
goto out_free_threads;
if (tid == prev_tid)
continue;
ntasks++;
nt = realloc(threads, sizeof(*threads) + sizeof(pid_t) * ntasks);
if (nt == NULL)
goto out_free_threads;
threads = nt;
threads->map[ntasks - 1] = tid;
threads->nr = ntasks;
}
out:
return threads;
out_free_threads:
free(threads);
threads = NULL;
goto out;
}
struct thread_map *thread_map__new_str(const char *pid, const char *tid,
uid_t uid)
{
if (pid)
return thread_map__new_by_pid_str(pid);
if (!tid && uid != UINT_MAX)
return thread_map__new_by_uid(uid);
return thread_map__new_by_tid_str(tid);
}
void thread_map__delete(struct thread_map *threads) void thread_map__delete(struct thread_map *threads)
{ {
free(threads); free(threads);
......
...@@ -13,6 +13,10 @@ struct thread_map *thread_map__new_by_pid(pid_t pid); ...@@ -13,6 +13,10 @@ struct thread_map *thread_map__new_by_pid(pid_t pid);
struct thread_map *thread_map__new_by_tid(pid_t tid); struct thread_map *thread_map__new_by_tid(pid_t tid);
struct thread_map *thread_map__new_by_uid(uid_t uid); struct thread_map *thread_map__new_by_uid(uid_t uid);
struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid); struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid);
struct thread_map *thread_map__new_str(const char *pid,
const char *tid, uid_t uid);
void thread_map__delete(struct thread_map *threads); void thread_map__delete(struct thread_map *threads);
size_t thread_map__fprintf(struct thread_map *threads, FILE *fp); size_t thread_map__fprintf(struct thread_map *threads, FILE *fp);
......
...@@ -69,11 +69,11 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) ...@@ -69,11 +69,11 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
ret += SNPRINTF(bf + ret, size - ret, "], "); ret += SNPRINTF(bf + ret, size - ret, "], ");
if (top->target_pid != -1) if (top->target_pid)
ret += SNPRINTF(bf + ret, size - ret, " (target_pid: %d", ret += SNPRINTF(bf + ret, size - ret, " (target_pid: %s",
top->target_pid); top->target_pid);
else if (top->target_tid != -1) else if (top->target_tid)
ret += SNPRINTF(bf + ret, size - ret, " (target_tid: %d", ret += SNPRINTF(bf + ret, size - ret, " (target_tid: %s",
top->target_tid); top->target_tid);
else if (top->uid_str != NULL) else if (top->uid_str != NULL)
ret += SNPRINTF(bf + ret, size - ret, " (uid: %s", ret += SNPRINTF(bf + ret, size - ret, " (uid: %s",
...@@ -85,7 +85,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) ...@@ -85,7 +85,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
ret += SNPRINTF(bf + ret, size - ret, ", CPU%s: %s)", ret += SNPRINTF(bf + ret, size - ret, ", CPU%s: %s)",
top->evlist->cpus->nr > 1 ? "s" : "", top->cpu_list); top->evlist->cpus->nr > 1 ? "s" : "", top->cpu_list);
else { else {
if (top->target_tid != -1) if (top->target_tid)
ret += SNPRINTF(bf + ret, size - ret, ")"); ret += SNPRINTF(bf + ret, size - ret, ")");
else else
ret += SNPRINTF(bf + ret, size - ret, ", %d CPU%s)", ret += SNPRINTF(bf + ret, size - ret, ", %d CPU%s)",
......
...@@ -23,7 +23,7 @@ struct perf_top { ...@@ -23,7 +23,7 @@ struct perf_top {
u64 guest_us_samples, guest_kernel_samples; u64 guest_us_samples, guest_kernel_samples;
int print_entries, count_filter, delay_secs; int print_entries, count_filter, delay_secs;
int freq; int freq;
pid_t target_pid, target_tid; const char *target_pid, *target_tid;
uid_t uid; uid_t uid;
bool hide_kernel_symbols, hide_user_symbols, zero; bool hide_kernel_symbols, hide_user_symbols, zero;
bool system_wide; bool system_wide;
...@@ -34,7 +34,8 @@ struct perf_top { ...@@ -34,7 +34,8 @@ struct perf_top {
bool vmlinux_warned; bool vmlinux_warned;
bool inherit; bool inherit;
bool group; bool group;
bool sample_id_all_avail; bool sample_id_all_missing;
bool exclude_guest_missing;
bool dump_symtab; bool dump_symtab;
const char *cpu_list; const char *cpu_list;
struct hist_entry *sym_filter_entry; struct hist_entry *sym_filter_entry;
......
...@@ -83,7 +83,7 @@ void warning(const char *warn, ...) ...@@ -83,7 +83,7 @@ void warning(const char *warn, ...)
va_end(params); va_end(params);
} }
uid_t parse_target_uid(const char *str, pid_t tid, pid_t pid) uid_t parse_target_uid(const char *str, const char *tid, const char *pid)
{ {
struct passwd pwd, *result; struct passwd pwd, *result;
char buf[1024]; char buf[1024];
...@@ -91,8 +91,8 @@ uid_t parse_target_uid(const char *str, pid_t tid, pid_t pid) ...@@ -91,8 +91,8 @@ uid_t parse_target_uid(const char *str, pid_t tid, pid_t pid)
if (str == NULL) if (str == NULL)
return UINT_MAX; return UINT_MAX;
/* CPU and PID are mutually exclusive */ /* UID and PID are mutually exclusive */
if (tid > 0 || pid > 0) { if (tid || pid) {
ui__warning("PID/TID switch overriding UID\n"); ui__warning("PID/TID switch overriding UID\n");
sleep(1); sleep(1);
return UINT_MAX; return UINT_MAX;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* XXX We need to find a better place for these things... * XXX We need to find a better place for these things...
*/ */
bool perf_host = true; bool perf_host = true;
bool perf_guest = true; bool perf_guest = false;
void event_attr_init(struct perf_event_attr *attr) void event_attr_init(struct perf_event_attr *attr)
{ {
...@@ -14,6 +14,8 @@ void event_attr_init(struct perf_event_attr *attr) ...@@ -14,6 +14,8 @@ void event_attr_init(struct perf_event_attr *attr)
attr->exclude_host = 1; attr->exclude_host = 1;
if (!perf_guest) if (!perf_guest)
attr->exclude_guest = 1; attr->exclude_guest = 1;
/* to capture ABI version */
attr->size = sizeof(*attr);
} }
int mkdir_p(char *path, mode_t mode) int mkdir_p(char *path, mode_t mode)
......
...@@ -199,6 +199,8 @@ static inline int has_extension(const char *filename, const char *ext) ...@@ -199,6 +199,8 @@ static inline int has_extension(const char *filename, const char *ext)
#undef isalpha #undef isalpha
#undef isprint #undef isprint
#undef isalnum #undef isalnum
#undef islower
#undef isupper
#undef tolower #undef tolower
#undef toupper #undef toupper
...@@ -219,6 +221,8 @@ extern unsigned char sane_ctype[256]; ...@@ -219,6 +221,8 @@ extern unsigned char sane_ctype[256];
#define isalpha(x) sane_istest(x,GIT_ALPHA) #define isalpha(x) sane_istest(x,GIT_ALPHA)
#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
#define isprint(x) sane_istest(x,GIT_PRINT) #define isprint(x) sane_istest(x,GIT_PRINT)
#define islower(x) (sane_istest(x,GIT_ALPHA) && sane_istest(x,0x20))
#define isupper(x) (sane_istest(x,GIT_ALPHA) && !sane_istest(x,0x20))
#define tolower(x) sane_case((unsigned char)(x), 0x20) #define tolower(x) sane_case((unsigned char)(x), 0x20)
#define toupper(x) sane_case((unsigned char)(x), 0) #define toupper(x) sane_case((unsigned char)(x), 0)
...@@ -245,7 +249,7 @@ struct perf_event_attr; ...@@ -245,7 +249,7 @@ struct perf_event_attr;
void event_attr_init(struct perf_event_attr *attr); void event_attr_init(struct perf_event_attr *attr);
uid_t parse_target_uid(const char *str, pid_t tid, pid_t pid); uid_t parse_target_uid(const char *str, const char *tid, const char *pid);
#define _STR(x) #x #define _STR(x) #x
#define STR(x) _STR(x) #define STR(x) _STR(x)
......
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