Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Configurable per thread proc map processing time out

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>

authored by

Kan Liang and committed by
Arnaldo Carvalho de Melo
9d9cad76 930e6fcd

+87 -31
+6
tools/perf/Documentation/perf-kvm.txt
··· 151 151 Show events other than HLT (x86 only) or Wait state (s390 only) 152 152 that take longer than duration usecs. 153 153 154 + --proc-map-timeout:: 155 + When processing pre-existing threads /proc/XXX/mmap, it may take 156 + a long time, because the file may be huge. A time out is needed 157 + in such cases. 158 + This option sets the time out limit. The default value is 500 ms. 159 + 154 160 SEE ALSO 155 161 -------- 156 162 linkperf:perf-top[1], linkperf:perf-record[1], linkperf:perf-report[1],
+5
tools/perf/Documentation/perf-record.txt
··· 271 271 snapshot can be specified. In Snapshot Mode, trace data is captured only when 272 272 signal SIGUSR2 is received. 273 273 274 + --proc-map-timeout:: 275 + When processing pre-existing threads /proc/XXX/mmap, it may take a long time, 276 + because the file may be huge. A time out is needed in such cases. 277 + This option sets the time out limit. The default value is 500 ms. 278 + 274 279 SEE ALSO 275 280 -------- 276 281 linkperf:perf-stat[1], linkperf:perf-list[1]
+6
tools/perf/Documentation/perf-top.txt
··· 201 201 Force each column width to the provided list, for large terminal 202 202 readability. 0 means no limit (default behavior). 203 203 204 + --proc-map-timeout:: 205 + When processing pre-existing threads /proc/XXX/mmap, it may take 206 + a long time, because the file may be huge. A time out is needed 207 + in such cases. 208 + This option sets the time out limit. The default value is 500 ms. 209 + 204 210 205 211 INTERACTIVE PROMPTING KEYS 206 212 --------------------------
+5
tools/perf/Documentation/perf-trace.txt
··· 121 121 --event:: 122 122 Trace other events, see 'perf list' for a complete list. 123 123 124 + --proc-map-timeout:: 125 + When processing pre-existing threads /proc/XXX/mmap, it may take a long time, 126 + because the file may be huge. A time out is needed in such cases. 127 + This option sets the time out limit. The default value is 500 ms. 128 + 124 129 PAGEFAULTS 125 130 ---------- 126 131
+4 -1
tools/perf/builtin-kvm.c
··· 1311 1311 "show events other than" 1312 1312 " HLT (x86 only) or Wait state (s390 only)" 1313 1313 " that take longer than duration usecs"), 1314 + OPT_UINTEGER(0, "proc-map-timeout", &kvm->opts.proc_map_timeout, 1315 + "per thread proc mmap processing timeout in ms"), 1314 1316 OPT_END() 1315 1317 }; 1316 1318 const char * const live_usage[] = { ··· 1340 1338 kvm->opts.target.uses_mmap = false; 1341 1339 kvm->opts.target.uid_str = NULL; 1342 1340 kvm->opts.target.uid = UINT_MAX; 1341 + kvm->opts.proc_map_timeout = 500; 1343 1342 1344 1343 symbol__init(NULL); 1345 1344 disable_buildid_cache(); ··· 1396 1393 perf_session__set_id_hdr_size(kvm->session); 1397 1394 ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true); 1398 1395 machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target, 1399 - kvm->evlist->threads, false); 1396 + kvm->evlist->threads, false, kvm->opts.proc_map_timeout); 1400 1397 err = kvm_live_open_events(kvm); 1401 1398 if (err) 1402 1399 goto out;
+5 -1
tools/perf/builtin-record.c
··· 598 598 } 599 599 600 600 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads, 601 - process_synthesized_event, opts->sample_address); 601 + process_synthesized_event, opts->sample_address, 602 + opts->proc_map_timeout); 602 603 if (err != 0) 603 604 goto out_child; 604 605 ··· 960 959 .uses_mmap = true, 961 960 .default_per_cpu = true, 962 961 }, 962 + .proc_map_timeout = 500, 963 963 }, 964 964 .tool = { 965 965 .sample = process_sample_event, ··· 1068 1066 parse_clockid), 1069 1067 OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts, 1070 1068 "opts", "AUX area tracing Snapshot Mode", ""), 1069 + OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout, 1070 + "per thread proc mmap processing timeout in ms"), 1071 1071 OPT_END() 1072 1072 }; 1073 1073
+4 -1
tools/perf/builtin-top.c
··· 977 977 goto out_delete; 978 978 979 979 machine__synthesize_threads(&top->session->machines.host, &opts->target, 980 - top->evlist->threads, false); 980 + top->evlist->threads, false, opts->proc_map_timeout); 981 981 ret = perf_top__start_counters(top); 982 982 if (ret) 983 983 goto out_delete; ··· 1087 1087 .target = { 1088 1088 .uses_mmap = true, 1089 1089 }, 1090 + .proc_map_timeout = 500, 1090 1091 }, 1091 1092 .max_stack = PERF_MAX_STACK_DEPTH, 1092 1093 .sym_pcnt_filter = 5, ··· 1187 1186 OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str, 1188 1187 "width[,width...]", 1189 1188 "don't try to adjust column width, use these fixed values"), 1189 + OPT_UINTEGER(0, "proc-map-timeout", &opts->proc_map_timeout, 1190 + "per thread proc mmap processing timeout in ms"), 1190 1191 OPT_END() 1191 1192 }; 1192 1193 const char * const top_usage[] = {
+5 -1
tools/perf/builtin-trace.c
··· 1518 1518 return -ENOMEM; 1519 1519 1520 1520 err = __machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target, 1521 - evlist->threads, trace__tool_process, false); 1521 + evlist->threads, trace__tool_process, false, 1522 + trace->opts.proc_map_timeout); 1522 1523 if (err) 1523 1524 symbol__exit(); 1524 1525 ··· 2748 2747 .user_interval = ULLONG_MAX, 2749 2748 .no_buffering = true, 2750 2749 .mmap_pages = UINT_MAX, 2750 + .proc_map_timeout = 500, 2751 2751 }, 2752 2752 .output = stdout, 2753 2753 .show_comm = true, ··· 2798 2796 "Trace pagefaults", parse_pagefaults, "maj"), 2799 2797 OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"), 2800 2798 OPT_BOOLEAN('f', "force", &trace.force, "don't complain, do it"), 2799 + OPT_UINTEGER(0, "proc-map-timeout", &trace.opts.proc_map_timeout, 2800 + "per thread proc mmap processing timeout in ms"), 2801 2801 OPT_END() 2802 2802 }; 2803 2803 const char * const trace_subcommands[] = { "record", NULL };
+1
tools/perf/perf.h
··· 69 69 unsigned initial_delay; 70 70 bool use_clockid; 71 71 clockid_t clockid; 72 + unsigned int proc_map_timeout; 72 73 }; 73 74 74 75 struct option;
+1 -1
tools/perf/tests/code-reading.c
··· 451 451 } 452 452 453 453 ret = perf_event__synthesize_thread_map(NULL, threads, 454 - perf_event__process, machine, false); 454 + perf_event__process, machine, false, 500); 455 455 if (ret < 0) { 456 456 pr_debug("perf_event__synthesize_thread_map failed\n"); 457 457 goto out_err;
+1 -1
tools/perf/tests/dwarf-unwind.c
··· 28 28 pid_t pid = getpid(); 29 29 30 30 return perf_event__synthesize_mmap_events(NULL, &event, pid, pid, 31 - mmap_handler, machine, true); 31 + mmap_handler, machine, true, 500); 32 32 } 33 33 34 34 #define MAX_STACK 8
+2 -2
tools/perf/tests/mmap-thread-lookup.c
··· 129 129 { 130 130 return perf_event__synthesize_threads(NULL, 131 131 perf_event__process, 132 - machine, 0); 132 + machine, 0, 500); 133 133 } 134 134 135 135 static int synth_process(struct machine *machine) ··· 141 141 142 142 err = perf_event__synthesize_thread_map(NULL, map, 143 143 perf_event__process, 144 - machine, 0); 144 + machine, 0, 500); 145 145 146 146 thread_map__delete(map); 147 147 return err;
+23 -13
tools/perf/util/event.c
··· 213 213 return 0; 214 214 } 215 215 216 - #define PROC_MAP_PARSE_TIMEOUT (500 * 1000000ULL) 217 - 218 216 int perf_event__synthesize_mmap_events(struct perf_tool *tool, 219 217 union perf_event *event, 220 218 pid_t pid, pid_t tgid, 221 219 perf_event__handler_t process, 222 220 struct machine *machine, 223 - bool mmap_data) 221 + bool mmap_data, 222 + unsigned int proc_map_timeout) 224 223 { 225 224 char filename[PATH_MAX]; 226 225 FILE *fp; 227 226 unsigned long long t; 228 227 bool truncation = false; 228 + unsigned long long timeout = proc_map_timeout * 1000000ULL; 229 229 int rc = 0; 230 230 231 231 if (machine__is_default_guest(machine)) ··· 258 258 if (fgets(bf, sizeof(bf), fp) == NULL) 259 259 break; 260 260 261 - if ((rdclock() - t) > PROC_MAP_PARSE_TIMEOUT) { 262 - pr_warning("Reading %s time out.\n", filename); 261 + if ((rdclock() - t) > timeout) { 262 + pr_warning("Reading %s time out. " 263 + "You may want to increase " 264 + "the time limit by --proc-map-timeout\n", 265 + filename); 263 266 truncation = true; 264 267 goto out; 265 268 } ··· 407 404 pid_t pid, int full, 408 405 perf_event__handler_t process, 409 406 struct perf_tool *tool, 410 - struct machine *machine, bool mmap_data) 407 + struct machine *machine, 408 + bool mmap_data, 409 + unsigned int proc_map_timeout) 411 410 { 412 411 char filename[PATH_MAX]; 413 412 DIR *tasks; ··· 426 421 return -1; 427 422 428 423 return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, 429 - process, machine, mmap_data); 424 + process, machine, mmap_data, 425 + proc_map_timeout); 430 426 } 431 427 432 428 if (machine__is_default_guest(machine)) ··· 468 462 if (_pid == pid) { 469 463 /* process the parent's maps too */ 470 464 rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, 471 - process, machine, mmap_data); 465 + process, machine, mmap_data, proc_map_timeout); 472 466 if (rc) 473 467 break; 474 468 } ··· 482 476 struct thread_map *threads, 483 477 perf_event__handler_t process, 484 478 struct machine *machine, 485 - bool mmap_data) 479 + bool mmap_data, 480 + unsigned int proc_map_timeout) 486 481 { 487 482 union perf_event *comm_event, *mmap_event, *fork_event; 488 483 int err = -1, thread, j; ··· 506 499 fork_event, 507 500 threads->map[thread], 0, 508 501 process, tool, machine, 509 - mmap_data)) { 502 + mmap_data, proc_map_timeout)) { 510 503 err = -1; 511 504 break; 512 505 } ··· 532 525 fork_event, 533 526 comm_event->comm.pid, 0, 534 527 process, tool, machine, 535 - mmap_data)) { 528 + mmap_data, proc_map_timeout)) { 536 529 err = -1; 537 530 break; 538 531 } ··· 549 542 550 543 int perf_event__synthesize_threads(struct perf_tool *tool, 551 544 perf_event__handler_t process, 552 - struct machine *machine, bool mmap_data) 545 + struct machine *machine, 546 + bool mmap_data, 547 + unsigned int proc_map_timeout) 553 548 { 554 549 DIR *proc; 555 550 char proc_path[PATH_MAX]; ··· 591 582 * one thread couldn't be synthesized. 592 583 */ 593 584 __event__synthesize_thread(comm_event, mmap_event, fork_event, pid, 594 - 1, process, tool, machine, mmap_data); 585 + 1, process, tool, machine, mmap_data, 586 + proc_map_timeout); 595 587 } 596 588 597 589 err = 0;
+6 -3
tools/perf/util/event.h
··· 384 384 int perf_event__synthesize_thread_map(struct perf_tool *tool, 385 385 struct thread_map *threads, 386 386 perf_event__handler_t process, 387 - struct machine *machine, bool mmap_data); 387 + struct machine *machine, bool mmap_data, 388 + unsigned int proc_map_timeout); 388 389 int perf_event__synthesize_threads(struct perf_tool *tool, 389 390 perf_event__handler_t process, 390 - struct machine *machine, bool mmap_data); 391 + struct machine *machine, bool mmap_data, 392 + unsigned int proc_map_timeout); 391 393 int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, 392 394 perf_event__handler_t process, 393 395 struct machine *machine); ··· 471 469 pid_t pid, pid_t tgid, 472 470 perf_event__handler_t process, 473 471 struct machine *machine, 474 - bool mmap_data); 472 + bool mmap_data, 473 + unsigned int proc_map_timeout); 475 474 476 475 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp); 477 476 size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp);
+4 -3
tools/perf/util/machine.c
··· 1913 1913 1914 1914 int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, 1915 1915 struct target *target, struct thread_map *threads, 1916 - perf_event__handler_t process, bool data_mmap) 1916 + perf_event__handler_t process, bool data_mmap, 1917 + unsigned int proc_map_timeout) 1917 1918 { 1918 1919 if (target__has_task(target)) 1919 - return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap); 1920 + return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap, proc_map_timeout); 1920 1921 else if (target__has_cpu(target)) 1921 - return perf_event__synthesize_threads(tool, process, machine, data_mmap); 1922 + return perf_event__synthesize_threads(tool, process, machine, data_mmap, proc_map_timeout); 1922 1923 /* command specified */ 1923 1924 return 0; 1924 1925 }
+6 -3
tools/perf/util/machine.h
··· 222 222 223 223 int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, 224 224 struct target *target, struct thread_map *threads, 225 - perf_event__handler_t process, bool data_mmap); 225 + perf_event__handler_t process, bool data_mmap, 226 + unsigned int proc_map_timeout); 226 227 static inline 227 228 int machine__synthesize_threads(struct machine *machine, struct target *target, 228 - struct thread_map *threads, bool data_mmap) 229 + struct thread_map *threads, bool data_mmap, 230 + unsigned int proc_map_timeout) 229 231 { 230 232 return __machine__synthesize_threads(machine, NULL, target, threads, 231 - perf_event__process, data_mmap); 233 + perf_event__process, data_mmap, 234 + proc_map_timeout); 232 235 } 233 236 234 237 pid_t machine__get_current_tid(struct machine *machine, int cpu);
+3 -1
tools/perf/util/session.c
··· 1368 1368 "not processed, if there are samples for addresses they\n" 1369 1369 "will not be resolved, you may find out which are these\n" 1370 1370 "threads by running with -v and redirecting the output\n" 1371 - "to a file.\n", 1371 + "to a file.\n" 1372 + "The time limit to process proc map is too short?\n" 1373 + "Increase it by --proc-map-timeout\n", 1372 1374 stats->nr_proc_map_timeout); 1373 1375 } 1374 1376 }