linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] perf: add support for per-event sampling period or frequency in perf record
@ 2010-11-23  9:45 Stephane Eranian
  2010-11-23 11:11 ` Peter Zijlstra
  0 siblings, 1 reply; 5+ messages in thread
From: Stephane Eranian @ 2010-11-23  9:45 UTC (permalink / raw)
  To: linux-kernel
  Cc: peterz, mingo, acme, paulus, davem, fweisbec, perfmon2-devel,
	eranian, eranian, robert.richter

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)

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] perf: add support for per-event sampling period or frequency in perf record
  2010-11-23  9:45 [PATCH] perf: add support for per-event sampling period or frequency in perf record Stephane Eranian
@ 2010-11-23 11:11 ` Peter Zijlstra
  2010-11-23 11:33   ` Stephane Eranian
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Zijlstra @ 2010-11-23 11:11 UTC (permalink / raw)
  To: eranian
  Cc: linux-kernel, mingo, acme, paulus, davem, fweisbec,
	perfmon2-devel, eranian, robert.richter

On Tue, 2010-11-23 at 11:45 +0200, Stephane Eranian wrote:
> 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


I remember an email not too long ago where people proposed to change the
syntax so that:

 -e evnt1,evnt2     -- create a group containing both events
 -e evnt1 -e evnt2  -- create two separate events

It would be nice to make sure these two proposals will not interfere.

Alternatively we extend the event syntax to include the period,
something like:

  -e evnt1:period=1234



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] perf: add support for per-event sampling period or frequency in perf record
  2010-11-23 11:11 ` Peter Zijlstra
@ 2010-11-23 11:33   ` Stephane Eranian
  2010-11-23 11:33     ` Stephane Eranian
  0 siblings, 1 reply; 5+ messages in thread
From: Stephane Eranian @ 2010-11-23 11:33 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: linux-kernel, mingo, acme, paulus, davem, fweisbec,
	perfmon2-devel, eranian, robert.richter

On Tue, Nov 23, 2010 at 12:11 PM, Peter Zijlstra <peterz@infradead.org> wrote:
> On Tue, 2010-11-23 at 11:45 +0200, Stephane Eranian wrote:
>> 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
>
>
> I remember an email not too long ago where people proposed to change the
> syntax so that:
>
>  -e evnt1,evnt2     -- create a group containing both events
>  -e evnt1 -e evnt2  -- create two separate events
>
Yes, that would be nice too especially for people interested in event ratios.

> It would be nice to make sure these two proposals will not interfere.
>
> Alternatively we extend the event syntax to include the period,
> something like:
>
>  -e evnt1:period=1234
>
Yes, that's the other approach. It may be more readable when you
have more events. I have that working with libpfm4, i.e., the full
event string is processed by the library. But for now, we could try
and do this in the tool as well, something like:

-e evtnt1:period=1234 -e evnt2:freq=100

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] perf: add support for per-event sampling period or frequency in perf record
  2010-11-23 11:33   ` Stephane Eranian
@ 2010-11-23 11:33     ` Stephane Eranian
  2010-11-23 11:42       ` Peter Zijlstra
  0 siblings, 1 reply; 5+ messages in thread
From: Stephane Eranian @ 2010-11-23 11:33 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: linux-kernel, mingo, acme, paulus, davem, fweisbec,
	perfmon2-devel, eranian, robert.richter

On Tue, Nov 23, 2010 at 12:33 PM, Stephane Eranian <eranian@google.com> wrote:
> On Tue, Nov 23, 2010 at 12:11 PM, Peter Zijlstra <peterz@infradead.org> wrote:
>> On Tue, 2010-11-23 at 11:45 +0200, Stephane Eranian wrote:
>>> 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
>>
>>
>> I remember an email not too long ago where people proposed to change the
>> syntax so that:
>>
>>  -e evnt1,evnt2     -- create a group containing both events
>>  -e evnt1 -e evnt2  -- create two separate events
>>
> Yes, that would be nice too especially for people interested in event ratios.
>
>> It would be nice to make sure these two proposals will not interfere.
>>
>> Alternatively we extend the event syntax to include the period,
>> something like:
>>
>>  -e evnt1:period=1234
>>
> Yes, that's the other approach. It may be more readable when you
> have more events. I have that working with libpfm4, i.e., the full
> event string is processed by the library. But for now, we could try
> and do this in the tool as well, something like:
>
> -e evtnt1:period=1234 -e evnt2:freq=100
>
Forgot to say, that the reason I did it thru -c and -F was to maintain
backward compatibility.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] perf: add support for per-event sampling period or frequency in perf record
  2010-11-23 11:33     ` Stephane Eranian
@ 2010-11-23 11:42       ` Peter Zijlstra
  0 siblings, 0 replies; 5+ messages in thread
From: Peter Zijlstra @ 2010-11-23 11:42 UTC (permalink / raw)
  To: Stephane Eranian
  Cc: linux-kernel, mingo, acme, paulus, davem, fweisbec,
	perfmon2-devel, eranian, robert.richter

On Tue, 2010-11-23 at 12:33 +0100, Stephane Eranian wrote:
> 
> Forgot to say, that the reason I did it thru -c and -F was to maintain
> backward compatibility. 

Right, we could keep the existing parameters to mean default values for
those events that didn't specify anything.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-11-23 11:42 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-23  9:45 [PATCH] perf: add support for per-event sampling period or frequency in perf record Stephane Eranian
2010-11-23 11:11 ` Peter Zijlstra
2010-11-23 11:33   ` Stephane Eranian
2010-11-23 11:33     ` Stephane Eranian
2010-11-23 11:42       ` Peter Zijlstra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).