From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752517AbcEAHkJ (ORCPT ); Sun, 1 May 2016 03:40:09 -0400 Received: from terminus.zytor.com ([198.137.202.10]:40344 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750789AbcEAHkG (ORCPT ); Sun, 1 May 2016 03:40:06 -0400 Date: Sun, 1 May 2016 00:39:51 -0700 From: tip-bot for Wang Nan Message-ID: Cc: hpa@zytor.com, mhiramat@kernel.org, wangnan0@huawei.com, acme@redhat.com, hekuang@huawei.com, linux-kernel@vger.kernel.org, adrian.hunter@intel.com, lizefan@huawei.com, mingo@kernel.org, tglx@linutronix.de, jolsa@redhat.com, namhyung@kernel.org Reply-To: mingo@kernel.org, tglx@linutronix.de, lizefan@huawei.com, adrian.hunter@intel.com, namhyung@kernel.org, jolsa@redhat.com, mhiramat@kernel.org, hpa@zytor.com, linux-kernel@vger.kernel.org, hekuang@huawei.com, acme@redhat.com, wangnan0@huawei.com In-Reply-To: <1461178794-40467-4-git-send-email-wangnan0@huawei.com> References: <1461178794-40467-4-git-send-email-wangnan0@huawei.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/core] perf record: Split output into multiple files via '--switch-output' Git-Commit-ID: 3c1cb7e3723caad9b4c1b2f816d86d8605296a4b X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 3c1cb7e3723caad9b4c1b2f816d86d8605296a4b Gitweb: http://git.kernel.org/tip/3c1cb7e3723caad9b4c1b2f816d86d8605296a4b Author: Wang Nan AuthorDate: Wed, 20 Apr 2016 18:59:50 +0000 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 28 Apr 2016 09:58:59 -0300 perf record: Split output into multiple files via '--switch-output' Allow 'perf record' to split its output into multiple files. For example: # ~/perf record -a --timestamp-filename --switch-output & [1] 10763 # kill -s SIGUSR2 10763 [ perf record: dump data: Woken up 1 times ] # [ perf record: Dump perf.data.2015122622314468 ] # kill -s SIGUSR2 10763 [ perf record: dump data: Woken up 1 times ] # [ perf record: Dump perf.data.2015122622314762 ] # kill -s SIGUSR2 10763 [ perf record: dump data: Woken up 1 times ] #[ perf record: Dump perf.data.2015122622315171 ] # fg perf record -a --timestamp-filename --switch-output ^C[ perf record: Woken up 1 times to write data ] [ perf record: Dump perf.data.2015122622315513 ] [ perf record: Captured and wrote 0.014 MB perf.data. (296 samples) ] # ls -l total 920 -rw------- 1 root root 797692 Dec 26 22:31 perf.data.2015122622314468 -rw------- 1 root root 59960 Dec 26 22:31 perf.data.2015122622314762 -rw------- 1 root root 59912 Dec 26 22:31 perf.data.2015122622315171 -rw------- 1 root root 19220 Dec 26 22:31 perf.data.2015122622315513 Signed-off-by: Wang Nan Tested-by: Arnaldo Carvalho de Melo Cc: Adrian Hunter Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1461178794-40467-4-git-send-email-wangnan0@huawei.com Signed-off-by: He Kuang [ Added man page entry, used the re-synthesize patch in this series as a fixup ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-record.txt | 8 +++++++ tools/perf/builtin-record.c | 40 ++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 19aa175..a77a431 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -347,6 +347,14 @@ Configure all used events to run in kernel space. --all-user:: Configure all used events to run in user space. +--switch-output:: +Generate multiple perf.data files, timestamp prefixed, switching to a new one +when receiving a SIGUSR2. + +A possible use case is to, given an external event, slice the perf.data file +that gets then processed, possibly via a perf script, to decide if that +particular perf.data snapshot should be kept or not. + SEE ALSO -------- linkperf:perf-stat[1], linkperf:perf-list[1] diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f4710c8..8ebe953 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -58,6 +58,7 @@ struct record { bool no_buildid_cache_set; bool buildid_all; bool timestamp_filename; + bool switch_output; unsigned long long samples; }; @@ -130,6 +131,7 @@ static volatile int child_finished; static volatile int auxtrace_record__snapshot_started; static DEFINE_TRIGGER(auxtrace_snapshot_trigger); +static DEFINE_TRIGGER(switch_output_trigger); static void sig_handler(int sig) { @@ -498,6 +500,8 @@ record__finish_output(struct record *rec) return; } +static int record__synthesize(struct record *rec); + static int record__switch_output(struct record *rec, bool at_exit) { @@ -526,6 +530,11 @@ record__switch_output(struct record *rec, bool at_exit) if (!quiet) fprintf(stderr, "[ perf record: Dump %s.%s ]\n", file->path, timestamp); + + /* Output tracking events */ + if (!at_exit) + record__synthesize(rec); + return fd; } @@ -650,9 +659,12 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); - if (rec->opts.auxtrace_snapshot_mode) { + if (rec->opts.auxtrace_snapshot_mode || rec->switch_output) { signal(SIGUSR2, snapshot_sig_handler); - trigger_on(&auxtrace_snapshot_trigger); + if (rec->opts.auxtrace_snapshot_mode) + trigger_on(&auxtrace_snapshot_trigger); + if (rec->switch_output) + trigger_on(&switch_output_trigger); } else { signal(SIGUSR2, SIG_IGN); } @@ -782,11 +794,13 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) } trigger_ready(&auxtrace_snapshot_trigger); + trigger_ready(&switch_output_trigger); for (;;) { unsigned long long hits = rec->samples; if (record__mmap_read_all(rec) < 0) { trigger_error(&auxtrace_snapshot_trigger); + trigger_error(&switch_output_trigger); err = -1; goto out_child; } @@ -802,6 +816,22 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) } } + if (trigger_is_hit(&switch_output_trigger)) { + trigger_ready(&switch_output_trigger); + + if (!quiet) + fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n", + waking); + waking = 0; + fd = record__switch_output(rec, false); + if (fd < 0) { + pr_err("Failed to switch to new file\n"); + trigger_error(&switch_output_trigger); + err = fd; + goto out_child; + } + } + if (hits == rec->samples) { if (done || draining) break; @@ -830,6 +860,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) } } trigger_off(&auxtrace_snapshot_trigger); + trigger_off(&switch_output_trigger); if (forks && workload_exec_errno) { char msg[STRERR_BUFSIZE]; @@ -1263,6 +1294,8 @@ struct option __record_options[] = { "Record build-id of all DSOs regardless of hits"), OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename, "append timestamp to output filename"), + OPT_BOOLEAN(0, "switch-output", &record.switch_output, + "Switch output when receive SIGUSR2"), OPT_END() }; @@ -1417,4 +1450,7 @@ static void snapshot_sig_handler(int sig __maybe_unused) if (auxtrace_record__snapshot_start(record.itr)) trigger_error(&auxtrace_snapshot_trigger); } + + if (trigger_is_ready(&switch_output_trigger)) + trigger_hit(&switch_output_trigger); }