Skip to content

Commit

Permalink
perf tools: Configurable per thread proc map processing time out
Browse files Browse the repository at this point in the history
The time out to limit the individual proc map processing was hard code
to 500ms. This patch introduce a new option --proc-map-timeout to make
the time limit configurable.

Signed-off-by: Kan Liang <kan.liang@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ying Huang <ying.huang@intel.com>
Link: http://lkml.kernel.org/r/1434549071-25611-2-git-send-email-kan.liang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Kan Liang authored and Arnaldo Carvalho de Melo committed Jun 19, 2015
1 parent 930e6fc commit 9d9cad7
Show file tree
Hide file tree
Showing 17 changed files with 87 additions and 31 deletions.
6 changes: 6 additions & 0 deletions tools/perf/Documentation/perf-kvm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ STAT LIVE OPTIONS
Show events other than HLT (x86 only) or Wait state (s390 only)
that take longer than duration usecs.

--proc-map-timeout::
When processing pre-existing threads /proc/XXX/mmap, it may take
a long time, because the file may be huge. A time out is needed
in such cases.
This option sets the time out limit. The default value is 500 ms.

SEE ALSO
--------
linkperf:perf-top[1], linkperf:perf-record[1], linkperf:perf-report[1],
Expand Down
5 changes: 5 additions & 0 deletions tools/perf/Documentation/perf-record.txt
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,11 @@ AUX area tracing event. Optionally the number of bytes to capture per
snapshot can be specified. In Snapshot Mode, trace data is captured only when
signal SIGUSR2 is received.

--proc-map-timeout::
When processing pre-existing threads /proc/XXX/mmap, it may take a long time,
because the file may be huge. A time out is needed in such cases.
This option sets the time out limit. The default value is 500 ms.

SEE ALSO
--------
linkperf:perf-stat[1], linkperf:perf-list[1]
6 changes: 6 additions & 0 deletions tools/perf/Documentation/perf-top.txt
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,12 @@ Default is to monitor all CPUS.
Force each column width to the provided list, for large terminal
readability. 0 means no limit (default behavior).

--proc-map-timeout::
When processing pre-existing threads /proc/XXX/mmap, it may take
a long time, because the file may be huge. A time out is needed
in such cases.
This option sets the time out limit. The default value is 500 ms.


INTERACTIVE PROMPTING KEYS
--------------------------
Expand Down
5 changes: 5 additions & 0 deletions tools/perf/Documentation/perf-trace.txt
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
--event::
Trace other events, see 'perf list' for a complete list.

--proc-map-timeout::
When processing pre-existing threads /proc/XXX/mmap, it may take a long time,
because the file may be huge. A time out is needed in such cases.
This option sets the time out limit. The default value is 500 ms.

PAGEFAULTS
----------

Expand Down
5 changes: 4 additions & 1 deletion tools/perf/builtin-kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1311,6 +1311,8 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
"show events other than"
" HLT (x86 only) or Wait state (s390 only)"
" that take longer than duration usecs"),
OPT_UINTEGER(0, "proc-map-timeout", &kvm->opts.proc_map_timeout,
"per thread proc mmap processing timeout in ms"),
OPT_END()
};
const char * const live_usage[] = {
Expand Down Expand Up @@ -1338,6 +1340,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
kvm->opts.target.uses_mmap = false;
kvm->opts.target.uid_str = NULL;
kvm->opts.target.uid = UINT_MAX;
kvm->opts.proc_map_timeout = 500;

symbol__init(NULL);
disable_buildid_cache();
Expand Down Expand Up @@ -1393,7 +1396,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
perf_session__set_id_hdr_size(kvm->session);
ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true);
machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target,
kvm->evlist->threads, false);
kvm->evlist->threads, false, kvm->opts.proc_map_timeout);
err = kvm_live_open_events(kvm);
if (err)
goto out;
Expand Down
6 changes: 5 additions & 1 deletion tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
}

err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
process_synthesized_event, opts->sample_address);
process_synthesized_event, opts->sample_address,
opts->proc_map_timeout);
if (err != 0)
goto out_child;

Expand Down Expand Up @@ -959,6 +960,7 @@ static struct record record = {
.uses_mmap = true,
.default_per_cpu = true,
},
.proc_map_timeout = 500,
},
.tool = {
.sample = process_sample_event,
Expand Down Expand Up @@ -1066,6 +1068,8 @@ struct option __record_options[] = {
parse_clockid),
OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
"opts", "AUX area tracing Snapshot Mode", ""),
OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
"per thread proc mmap processing timeout in ms"),
OPT_END()
};

Expand Down
5 changes: 4 additions & 1 deletion tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ static int __cmd_top(struct perf_top *top)
goto out_delete;

machine__synthesize_threads(&top->session->machines.host, &opts->target,
top->evlist->threads, false);
top->evlist->threads, false, opts->proc_map_timeout);
ret = perf_top__start_counters(top);
if (ret)
goto out_delete;
Expand Down Expand Up @@ -1087,6 +1087,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
.target = {
.uses_mmap = true,
},
.proc_map_timeout = 500,
},
.max_stack = PERF_MAX_STACK_DEPTH,
.sym_pcnt_filter = 5,
Expand Down Expand Up @@ -1186,6 +1187,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
"width[,width...]",
"don't try to adjust column width, use these fixed values"),
OPT_UINTEGER(0, "proc-map-timeout", &opts->proc_map_timeout,
"per thread proc mmap processing timeout in ms"),
OPT_END()
};
const char * const top_usage[] = {
Expand Down
6 changes: 5 additions & 1 deletion tools/perf/builtin-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1518,7 +1518,8 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
return -ENOMEM;

err = __machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target,
evlist->threads, trace__tool_process, false);
evlist->threads, trace__tool_process, false,
trace->opts.proc_map_timeout);
if (err)
symbol__exit();

Expand Down Expand Up @@ -2747,6 +2748,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
.user_interval = ULLONG_MAX,
.no_buffering = true,
.mmap_pages = UINT_MAX,
.proc_map_timeout = 500,
},
.output = stdout,
.show_comm = true,
Expand Down Expand Up @@ -2796,6 +2798,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
"Trace pagefaults", parse_pagefaults, "maj"),
OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"),
OPT_BOOLEAN('f', "force", &trace.force, "don't complain, do it"),
OPT_UINTEGER(0, "proc-map-timeout", &trace.opts.proc_map_timeout,
"per thread proc mmap processing timeout in ms"),
OPT_END()
};
const char * const trace_subcommands[] = { "record", NULL };
Expand Down
1 change: 1 addition & 0 deletions tools/perf/perf.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ struct record_opts {
unsigned initial_delay;
bool use_clockid;
clockid_t clockid;
unsigned int proc_map_timeout;
};

struct option;
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/tests/code-reading.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ static int do_test_code_reading(bool try_kcore)
}

ret = perf_event__synthesize_thread_map(NULL, threads,
perf_event__process, machine, false);
perf_event__process, machine, false, 500);
if (ret < 0) {
pr_debug("perf_event__synthesize_thread_map failed\n");
goto out_err;
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/tests/dwarf-unwind.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static int init_live_machine(struct machine *machine)
pid_t pid = getpid();

return perf_event__synthesize_mmap_events(NULL, &event, pid, pid,
mmap_handler, machine, true);
mmap_handler, machine, true, 500);
}

#define MAX_STACK 8
Expand Down
4 changes: 2 additions & 2 deletions tools/perf/tests/mmap-thread-lookup.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ static int synth_all(struct machine *machine)
{
return perf_event__synthesize_threads(NULL,
perf_event__process,
machine, 0);
machine, 0, 500);
}

static int synth_process(struct machine *machine)
Expand All @@ -141,7 +141,7 @@ static int synth_process(struct machine *machine)

err = perf_event__synthesize_thread_map(NULL, map,
perf_event__process,
machine, 0);
machine, 0, 500);

thread_map__delete(map);
return err;
Expand Down
36 changes: 23 additions & 13 deletions tools/perf/util/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,19 +213,19 @@ static int perf_event__synthesize_fork(struct perf_tool *tool,
return 0;
}

#define PROC_MAP_PARSE_TIMEOUT (500 * 1000000ULL)

int perf_event__synthesize_mmap_events(struct perf_tool *tool,
union perf_event *event,
pid_t pid, pid_t tgid,
perf_event__handler_t process,
struct machine *machine,
bool mmap_data)
bool mmap_data,
unsigned int proc_map_timeout)
{
char filename[PATH_MAX];
FILE *fp;
unsigned long long t;
bool truncation = false;
unsigned long long timeout = proc_map_timeout * 1000000ULL;
int rc = 0;

if (machine__is_default_guest(machine))
Expand Down Expand Up @@ -258,8 +258,11 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool,
if (fgets(bf, sizeof(bf), fp) == NULL)
break;

if ((rdclock() - t) > PROC_MAP_PARSE_TIMEOUT) {
pr_warning("Reading %s time out.\n", filename);
if ((rdclock() - t) > timeout) {
pr_warning("Reading %s time out. "
"You may want to increase "
"the time limit by --proc-map-timeout\n",
filename);
truncation = true;
goto out;
}
Expand Down Expand Up @@ -404,7 +407,9 @@ static int __event__synthesize_thread(union perf_event *comm_event,
pid_t pid, int full,
perf_event__handler_t process,
struct perf_tool *tool,
struct machine *machine, bool mmap_data)
struct machine *machine,
bool mmap_data,
unsigned int proc_map_timeout)
{
char filename[PATH_MAX];
DIR *tasks;
Expand All @@ -421,7 +426,8 @@ static int __event__synthesize_thread(union perf_event *comm_event,
return -1;

return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
process, machine, mmap_data);
process, machine, mmap_data,
proc_map_timeout);
}

if (machine__is_default_guest(machine))
Expand Down Expand Up @@ -462,7 +468,7 @@ static int __event__synthesize_thread(union perf_event *comm_event,
if (_pid == pid) {
/* process the parent's maps too */
rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
process, machine, mmap_data);
process, machine, mmap_data, proc_map_timeout);
if (rc)
break;
}
Expand All @@ -476,7 +482,8 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
struct thread_map *threads,
perf_event__handler_t process,
struct machine *machine,
bool mmap_data)
bool mmap_data,
unsigned int proc_map_timeout)
{
union perf_event *comm_event, *mmap_event, *fork_event;
int err = -1, thread, j;
Expand All @@ -499,7 +506,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
fork_event,
threads->map[thread], 0,
process, tool, machine,
mmap_data)) {
mmap_data, proc_map_timeout)) {
err = -1;
break;
}
Expand All @@ -525,7 +532,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
fork_event,
comm_event->comm.pid, 0,
process, tool, machine,
mmap_data)) {
mmap_data, proc_map_timeout)) {
err = -1;
break;
}
Expand All @@ -542,7 +549,9 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,

int perf_event__synthesize_threads(struct perf_tool *tool,
perf_event__handler_t process,
struct machine *machine, bool mmap_data)
struct machine *machine,
bool mmap_data,
unsigned int proc_map_timeout)
{
DIR *proc;
char proc_path[PATH_MAX];
Expand Down Expand Up @@ -582,7 +591,8 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
* one thread couldn't be synthesized.
*/
__event__synthesize_thread(comm_event, mmap_event, fork_event, pid,
1, process, tool, machine, mmap_data);
1, process, tool, machine, mmap_data,
proc_map_timeout);
}

err = 0;
Expand Down
9 changes: 6 additions & 3 deletions tools/perf/util/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,10 +384,12 @@ typedef int (*perf_event__handler_t)(struct perf_tool *tool,
int perf_event__synthesize_thread_map(struct perf_tool *tool,
struct thread_map *threads,
perf_event__handler_t process,
struct machine *machine, bool mmap_data);
struct machine *machine, bool mmap_data,
unsigned int proc_map_timeout);
int perf_event__synthesize_threads(struct perf_tool *tool,
perf_event__handler_t process,
struct machine *machine, bool mmap_data);
struct machine *machine, bool mmap_data,
unsigned int proc_map_timeout);
int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
perf_event__handler_t process,
struct machine *machine);
Expand Down Expand Up @@ -469,7 +471,8 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool,
pid_t pid, pid_t tgid,
perf_event__handler_t process,
struct machine *machine,
bool mmap_data);
bool mmap_data,
unsigned int proc_map_timeout);

size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp);
size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp);
Expand Down
7 changes: 4 additions & 3 deletions tools/perf/util/machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -1913,12 +1913,13 @@ int machines__for_each_thread(struct machines *machines,

int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
struct target *target, struct thread_map *threads,
perf_event__handler_t process, bool data_mmap)
perf_event__handler_t process, bool data_mmap,
unsigned int proc_map_timeout)
{
if (target__has_task(target))
return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap, proc_map_timeout);
else if (target__has_cpu(target))
return perf_event__synthesize_threads(tool, process, machine, data_mmap);
return perf_event__synthesize_threads(tool, process, machine, data_mmap, proc_map_timeout);
/* command specified */
return 0;
}
Expand Down
9 changes: 6 additions & 3 deletions tools/perf/util/machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,16 @@ int machines__for_each_thread(struct machines *machines,

int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
struct target *target, struct thread_map *threads,
perf_event__handler_t process, bool data_mmap);
perf_event__handler_t process, bool data_mmap,
unsigned int proc_map_timeout);
static inline
int machine__synthesize_threads(struct machine *machine, struct target *target,
struct thread_map *threads, bool data_mmap)
struct thread_map *threads, bool data_mmap,
unsigned int proc_map_timeout)
{
return __machine__synthesize_threads(machine, NULL, target, threads,
perf_event__process, data_mmap);
perf_event__process, data_mmap,
proc_map_timeout);
}

pid_t machine__get_current_tid(struct machine *machine, int cpu);
Expand Down
4 changes: 3 additions & 1 deletion tools/perf/util/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -1368,7 +1368,9 @@ static void perf_session__warn_about_errors(const struct perf_session *session)
"not processed, if there are samples for addresses they\n"
"will not be resolved, you may find out which are these\n"
"threads by running with -v and redirecting the output\n"
"to a file.\n",
"to a file.\n"
"The time limit to process proc map is too short?\n"
"Increase it by --proc-map-timeout\n",
stats->nr_proc_map_timeout);
}
}
Expand Down

0 comments on commit 9d9cad7

Please sign in to comment.