From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757264AbbFQPKr (ORCPT ); Wed, 17 Jun 2015 11:10:47 -0400 Received: from mga01.intel.com ([192.55.52.88]:44259 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756756AbbFQPKo (ORCPT ); Wed, 17 Jun 2015 11:10:44 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,633,1427785200"; d="scan'208";a="729268967" From: kan.liang@intel.com To: acme@kernel.org Cc: linux-kernel@vger.kernel.org, dsahern@gmail.com, ying.huang@intel.com, andi@firstfloor.org, Kan Liang Subject: [PATCH V3 1/2] perf,tools: add time out to force stop proc map processing Date: Wed, 17 Jun 2015 03:56:51 -0400 Message-Id: <1434527812-17051-1-git-send-email-kan.liang@intel.com> X-Mailer: git-send-email 1.8.3.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Kan Liang System wide sampling like 'perf top' or 'perf record -a' read all threads /proc/xxx/maps before sampling. If there are any threads which generating a keeping growing huge maps, perf will do infinite loop during synthesizing. Nothing will be sampled. This patch fixes this issue by adding per-thread timeout to force stop this kind of endless proc map processing. PERF_RECORD_MISC_MMAP_TIME_OUT is introduced to indicate that the mmap record are truncated by time out. User will get warning notification when truncated mmap records are detected. Reported-by: Huang, Ying Signed-off-by: Kan Liang --- Changes since V1 - Add warning message for time out. Changes since V2 - Handle time out warning in perf_session__warn_about_errors - Configurable time out (patch 2/2) include/uapi/linux/perf_event.h | 4 ++++ tools/perf/util/event.c | 18 ++++++++++++++++++ tools/perf/util/event.h | 1 + tools/perf/util/session.c | 11 +++++++++++ 4 files changed, 34 insertions(+) diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index 613ed9a..b3904ba 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -566,6 +566,10 @@ struct perf_event_mmap_page { #define PERF_RECORD_MISC_GUEST_USER (5 << 0) /* + * Indicates that /proc/PID/maps parsing are truncated by time out. + */ +#define PERF_RECORD_MISC_MMAP_TIME_OUT (1 << 12) +/* * PERF_RECORD_MISC_MMAP_DATA and PERF_RECORD_MISC_COMM_EXEC are used on * different events so can reuse the same bit position. */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 793b150..ac6cf2a 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -213,6 +213,8 @@ static int perf_event__synthesize_fork(struct perf_tool *tool, return 0; } +#define MMAP_TIMEOUT (50 * 1000000ULL) + int perf_event__synthesize_mmap_events(struct perf_tool *tool, union perf_event *event, pid_t pid, pid_t tgid, @@ -222,6 +224,8 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, { char filename[PATH_MAX]; FILE *fp; + unsigned long long t; + bool timeout = false; int rc = 0; if (machine__is_default_guest(machine)) @@ -240,6 +244,7 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, } event->header.type = PERF_RECORD_MMAP2; + t = rdclock(); while (1) { char bf[BUFSIZ]; @@ -253,6 +258,12 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, if (fgets(bf, sizeof(bf), fp) == NULL) break; + if ((rdclock() - t) > MMAP_TIMEOUT) { + pr_warning("Reading %s time out.\n", filename); + timeout = true; + goto out; + } + /* ensure null termination since stack will be reused. */ strcpy(execname, ""); @@ -301,6 +312,10 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, event->header.misc |= PERF_RECORD_MISC_MMAP_DATA; } +out: + if (timeout) + event->header.misc |= PERF_RECORD_MISC_MMAP_TIME_OUT; + if (!strcmp(execname, "")) strcpy(execname, anonstr); @@ -319,6 +334,9 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, rc = -1; break; } + + if (timeout) + break; } fclose(fp); diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 5dc51ad..39868f5 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -265,6 +265,7 @@ struct events_stats { u32 nr_unknown_id; u32 nr_unprocessable_samples; u32 nr_auxtrace_errors[PERF_AUXTRACE_ERROR_MAX]; + u32 nr_proc_map_timeout; }; struct attr_event { diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 88d87bf..8561d8b 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1041,6 +1041,8 @@ static int machines__deliver_event(struct machines *machines, case PERF_RECORD_MMAP: return tool->mmap(tool, event, sample, machine); case PERF_RECORD_MMAP2: + if (event->header.misc & PERF_RECORD_MISC_MMAP_TIME_OUT) + ++evlist->stats.nr_proc_map_timeout; return tool->mmap2(tool, event, sample, machine); case PERF_RECORD_COMM: return tool->comm(tool, event, sample, machine); @@ -1337,6 +1339,15 @@ static void perf_session__warn_about_errors(const struct perf_session *session) ui__warning("%u out of order events recorded.\n", oe->nr_unordered_events); events_stats__auxtrace_error_warn(stats); + + if (stats->nr_proc_map_timeout != 0) { + ui__warning("%d map information files for pre-existing threads were\n" + "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", + stats->nr_proc_map_timeout); + } } volatile int session_done; -- 1.8.3.1