From: Stephane Eranian <eranian@google.com>
To: linux-kernel@vger.kernel.org
Cc: peterz@infradead.org, mingo@elte.hu, acme@redhat.com,
paulus@samba.org, davem@davemloft.net, fweisbec@gmail.com,
perfmon2-devel@lists.sf.net, eranian@gmail.com,
eranian@google.com, robert.richter@amd.com
Subject: [PATCH] perf: add support for per-event sampling period or frequency in perf record
Date: Tue, 23 Nov 2010 11:45:05 +0200 [thread overview]
Message-ID: <4ceb9b74.e6edd80a.3271.fffff742@mx.google.com> (raw)
This patch allows specifying a per event sampling period or frequency.
Up until now, the same sampling period or frequency was applied to all
the events specified on the command line of perf record. A sampling
period depends on the event, thus it is necessary to specify it per event.
With this patch, both the -F and -c options now take a comma separated
list of values. If a value is omitted for an event, it defaults to 1000Hz
frequency mode as before.
$ perf record -e cycles,instructions -c 100000,200000 -a -- sleep 5
Signed-off-by: Stephane Eranian <eranian@google.com>
---
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 9426383..28ea0a5 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -35,14 +35,10 @@ enum write_mode_t {
static int *fd[MAX_NR_CPUS][MAX_COUNTERS];
-static u64 user_interval = ULLONG_MAX;
-static u64 default_interval = 0;
-
static int nr_cpus = 0;
static unsigned int page_size;
static unsigned int mmap_pages = 128;
-static unsigned int user_freq = UINT_MAX;
-static int freq = 1000;
+static u64 default_freq = 1000;
static int output;
static int pipe_output = 0;
static const char *output_name = "perf.data";
@@ -85,6 +81,97 @@ struct mmap_data {
};
static struct mmap_data mmap_array[MAX_NR_CPUS];
+static u64 user_periods[MAX_COUNTERS];
+static u64 user_freqs[MAX_COUNTERS];
+static int nr_user_freqs;
+static int nr_user_periods;
+
+static int parse_user_freqs(const struct option *opt __used, const char *str,
+ int unset __used)
+{
+ const char *p, *e, *eos = str + strlen(str);
+ int n = 0, ret = 0;
+ for (;;) {
+ p = strchr(str, ',');
+ e = p ? p : eos;
+
+ if (n == MAX_COUNTERS)
+ goto error;
+ /* allow empty cgroups, i.e., skip */
+ if (e - str) {
+ /* termination added */
+ ret = sscanf(str, "%llu", user_freqs+n);
+ if (ret != 1)
+ goto error;
+ if (!user_freqs[n])
+ goto error_zero;
+ if (user_periods[n])
+ goto error_mix;
+ nr_user_freqs++;
+ } else {
+ user_freqs[n] = 0;
+ }
+ n++;
+ if (!p)
+ break;
+ str = p+1;
+ }
+ return 0;
+error:
+ fprintf(stderr, "cannot parse event frequency %s\n", str);
+ return -1;
+error_zero:
+ fprintf(stderr, "invalid zero frequency, aborting");
+ return -1;
+error_mix:
+ fprintf(stderr, "event %d has both a frequency and period,"
+ " must choose only one, aborting", n);
+ return -1;
+}
+
+static int parse_user_periods(const struct option *opt __used, const char *str,
+ int unset __used)
+{
+ const char *p, *e, *eos = str + strlen(str);
+ int n = 0, ret;
+
+ for (;;) {
+ p = strchr(str, ',');
+ e = p ? p : eos;
+
+ if (n == MAX_COUNTERS)
+ goto error;
+ /* allow empty cgroups, i.e., skip */
+ if (e - str) {
+ /* termination added */
+ ret = sscanf(str, "%llu", user_periods+n);
+ if (ret != 1)
+ goto error;
+ if (!user_periods[n])
+ goto error_zero;
+ if (user_freqs[n])
+ goto error_mix;
+ nr_user_periods++;
+ } else {
+ user_periods[n] = 0;
+ }
+ n++;
+ if (!p)
+ break;
+ str = p+1;
+ }
+ return 0;
+error:
+ fprintf(stderr, "cannot parse event frequency %s\n", str);
+ return -1;
+error_zero:
+ fprintf(stderr, "invalid zero period, aborting");
+ return -1;
+error_mix:
+ fprintf(stderr, "event %d has both a frequency and period,"
+ " must choose only one, aborting", n);
+ return -1;
+}
static unsigned long mmap_read_head(struct mmap_data *md)
{
@@ -232,6 +319,7 @@ static void create_counter(int counter, int cpu)
struct perf_header_attr *h_attr;
int track = !counter; /* only the first counter needs these */
int thread_index;
+ u64 ufreq, uperiod;
int ret;
struct {
u64 count;
@@ -249,18 +337,19 @@ static void create_counter(int counter, int cpu)
if (nr_counters > 1)
attr->sample_type |= PERF_SAMPLE_ID;
+ ufreq = user_freqs[counter];
+ uperiod = user_periods[counter];
/*
- * We default some events to a 1 default interval. But keep
+ * We default some events to a 1 default period. But keep
* it a weak assumption overridable by the user.
*/
- if (!attr->sample_period || (user_freq != UINT_MAX &&
- user_interval != ULLONG_MAX)) {
- if (freq) {
- attr->sample_type |= PERF_SAMPLE_PERIOD;
- attr->freq = 1;
- attr->sample_freq = freq;
+ if (!attr->sample_period || ufreq != 0 || uperiod != 0) {
+ if (uperiod) {
+ attr->sample_period = uperiod;
} else {
- attr->sample_period = default_interval;
+ attr->sample_type |= PERF_SAMPLE_PERIOD;
+ attr->freq = 1;
+ attr->sample_freq = ufreq ? ufreq : default_freq;
}
}
@@ -866,12 +955,14 @@ const struct option record_options[] = {
"list of cpus to monitor"),
OPT_BOOLEAN('f', "force", &force,
"overwrite existing data file (deprecated)"),
- OPT_U64('c', "count", &user_interval, "event period to sample"),
+ OPT_CALLBACK('c', "count", NULL, "period", "profile events at these "
+ " periods", parse_user_periods),
OPT_STRING('o', "output", &output_name, "file",
"output file name"),
OPT_BOOLEAN('i', "no-inherit", &no_inherit,
"child tasks do not inherit counters"),
- OPT_UINTEGER('F', "freq", &user_freq, "profile at this frequency"),
+ OPT_CALLBACK('F', "freq", NULL, "freq", "profile events at these "
+ " frequencies", parse_user_freqs),
OPT_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"),
OPT_BOOLEAN('g', "call-graph", &call_graph,
"do call-graph (stack chain/backtrace) recording"),
@@ -947,27 +1038,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
if (!event_array)
goto out_free_fd;
- if (user_interval != ULLONG_MAX)
- default_interval = user_interval;
- if (user_freq != UINT_MAX)
- freq = user_freq;
-
- /*
- * User specified count overrides default frequency.
- */
- if (default_interval)
- freq = 0;
- else if (freq) {
- default_interval = freq;
- } else {
- fprintf(stderr, "frequency and count are zero, aborting\n");
- err = -EINVAL;
- goto out_free_event_array;
- }
-
err = __cmd_record(argc, argv);
-out_free_event_array:
free(event_array);
out_free_fd:
for (i = 0; i < MAX_NR_CPUS; i++) {
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 492d19d..c53cd10 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -543,7 +543,11 @@ static char *get_script_path(const char *script_root, const char *suffix)
static bool is_top_script(const char *script_path)
{
- return ends_with((char *)script_path, "top") == NULL ? false : true;
+ char *str = strdup(script_path);
+ int ret;
+ ret = ends_with(str, "top") == NULL ? false : true;
+ free(str);
+ return ret;
}
static int has_required_arg(char *script_path)
next reply other threads:[~2010-11-23 10:46 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-23 9:45 Stephane Eranian [this message]
2010-11-23 11:11 ` [PATCH] perf: add support for per-event sampling period or frequency in perf record Peter Zijlstra
2010-11-23 11:33 ` Stephane Eranian
2010-11-23 11:33 ` Stephane Eranian
2010-11-23 11:42 ` Peter Zijlstra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4ceb9b74.e6edd80a.3271.fffff742@mx.google.com \
--to=eranian@google.com \
--cc=acme@redhat.com \
--cc=davem@davemloft.net \
--cc=eranian@gmail.com \
--cc=fweisbec@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=paulus@samba.org \
--cc=perfmon2-devel@lists.sf.net \
--cc=peterz@infradead.org \
--cc=robert.richter@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.