All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch] perf stat: --repeat forever
@ 2013-02-15 22:28 Frederik Deweerdt
  2013-02-18 15:04 ` Arnaldo Carvalho de Melo
  2013-03-01 18:02 ` [patch v2] " Frederik Deweerdt
  0 siblings, 2 replies; 5+ messages in thread
From: Frederik Deweerdt @ 2013-02-15 22:28 UTC (permalink / raw)
  To: a.p.zijlstra, paulus, mingo, acme; +Cc: linux-kernel

Hi,

The following patch causes 'perf stat --repeat 0' to be interpreted as
'forever', displaying the stats for every run.

We act as if a single run was asked, and reset the stats in each
iteration. In this mode SIGINT is passed to perf to be able to stop the
loop with Ctrl+C.

Regards,
Frederik


Signed-off-by: Frederik Deweerdt <frederik.deweerdt@gmail.com>

diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index cf0c310..784976a 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -52,7 +52,7 @@ OPTIONS
 
 -r::
 --repeat=<n>::
-	repeat command and print average + stddev (max: 100)
+	repeat command and print average + stddev (max: 100). 0 means forever.
 
 -B::
 --big-num::
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index c247fac..b02b3a9 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -87,6 +87,7 @@ static FILE			*output				= NULL;
 static const char		*pre_cmd			= NULL;
 static const char		*post_cmd			= NULL;
 static bool			sync_run			= false;
+static bool			forever				= false;
 
 static volatile int done = 0;
 
@@ -94,6 +95,11 @@ struct perf_stat {
 	struct stats	  res_stats[3];
 };
 
+static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
+{
+	memset(evsel->priv, 0, sizeof(struct perf_stat));
+}
+
 static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
 {
 	evsel->priv = zalloc(sizeof(struct perf_stat));
@@ -129,6 +135,22 @@ static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
 static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
 static struct stats walltime_nsecs_stats;
 
+static void reset_stats(void)
+{
+	memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
+	memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
+	memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
+	memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats));
+	memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats));
+	memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats));
+	memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats));
+	memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats));
+	memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
+	memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
+	memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
+	memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
+}
+
 static int create_perf_stat_counter(struct perf_evsel *evsel)
 {
 	struct perf_event_attr *attr = &evsel->attr;
@@ -1120,7 +1142,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 	OPT_INCR('v', "verbose", &verbose,
 		    "be more verbose (show counter open errors, etc)"),
 	OPT_INTEGER('r', "repeat", &run_count,
-		    "repeat command and print average + stddev (max: 100)"),
+		    "repeat command and print average + stddev (max: 100, forever: 0)"),
 	OPT_BOOLEAN('n', "null", &null_run,
 		    "null run - dont start any counters"),
 	OPT_INCR('d', "detailed", &detailed_run,
@@ -1220,8 +1242,12 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 
 	if (!argc && !perf_target__has_task(&target))
 		usage_with_options(stat_usage, options);
-	if (run_count <= 0)
+	if (run_count < 0) {
 		usage_with_options(stat_usage, options);
+	} else if (run_count == 0) {
+		forever = true;
+		run_count = 1;
+	}
 
 	/* no_aggr, cgroup are for system-wide only */
 	if ((no_aggr || nr_cgroups) && !perf_target__has_cpu(&target)) {
@@ -1259,21 +1285,31 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 	 * task, but being ignored by perf stat itself:
 	 */
 	atexit(sig_atexit);
-	signal(SIGINT,  skip_signal);
+	if (!forever)
+		signal(SIGINT,  skip_signal);
 	signal(SIGALRM, skip_signal);
 	signal(SIGABRT, skip_signal);
 
 	status = 0;
-	for (run_idx = 0; run_idx < run_count; run_idx++) {
+	for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
 		if (run_count != 1 && verbose)
 			fprintf(output, "[ perf stat: executing run #%d ... ]\n",
-				run_idx + 1);
+					run_idx + 1);
 
 		status = run_perf_stat(argc, argv);
+		if (forever && status != -1) {
+			print_stat(argc, argv);
+			list_for_each_entry(pos, &evsel_list->entries, node) {
+				perf_evsel__reset_stat_priv(pos);
+				perf_evsel__reset_counts(pos, perf_evsel__nr_cpus(pos));
+			}
+			reset_stats();
+		}
 	}
 
-	if (status != -1)
+	if (!forever && status != -1)
 		print_stat(argc, argv);
+
 out_free_fd:
 	list_for_each_entry(pos, &evsel_list->entries, node)
 		perf_evsel__free_stat_priv(pos);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 1b16dd1..0c49e79 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -580,6 +580,12 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
 	return 0;
 }
 
+void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus)
+{
+	memset(evsel->counts, 0, (sizeof(*evsel->counts) +
+				 (ncpus * sizeof(struct perf_counts_values))));
+}
+
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
 {
 	evsel->counts = zalloc((sizeof(*evsel->counts) +
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 3d2b801..364d820 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -114,6 +114,7 @@ const char *perf_evsel__name(struct perf_evsel *evsel);
 int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
 int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
+void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus);
 void perf_evsel__free_fd(struct perf_evsel *evsel);
 void perf_evsel__free_id(struct perf_evsel *evsel);
 void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);

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

* Re: [patch] perf stat: --repeat forever
  2013-02-15 22:28 [patch] perf stat: --repeat forever Frederik Deweerdt
@ 2013-02-18 15:04 ` Arnaldo Carvalho de Melo
  2013-02-18 17:24   ` Frederik Deweerdt
  2013-03-01 18:02 ` [patch v2] " Frederik Deweerdt
  1 sibling, 1 reply; 5+ messages in thread
From: Arnaldo Carvalho de Melo @ 2013-02-18 15:04 UTC (permalink / raw)
  To: Frederik Deweerdt; +Cc: a.p.zijlstra, paulus, mingo, linux-kernel

Em Fri, Feb 15, 2013 at 05:28:49PM -0500, Frederik Deweerdt escreveu:
> Hi,
> 
> The following patch causes 'perf stat --repeat 0' to be interpreted as
> 'forever', displaying the stats for every run.
> 
> We act as if a single run was asked, and reset the stats in each
> iteration. In this mode SIGINT is passed to perf to be able to stop the
> loop with Ctrl+C.

It is not applying to my perf/core branch, please take a look at:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

branch perf/core

Also please consider removing the need to specify 0, i.e. I think this
is possible and shorter:

# perf stat -a --repeat sleep 1

- Arnaldo
 
> Regards,
> Frederik
> 
> 
> Signed-off-by: Frederik Deweerdt <frederik.deweerdt@gmail.com>
> 
> diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
> index cf0c310..784976a 100644
> --- a/tools/perf/Documentation/perf-stat.txt
> +++ b/tools/perf/Documentation/perf-stat.txt
> @@ -52,7 +52,7 @@ OPTIONS
>  
>  -r::
>  --repeat=<n>::
> -	repeat command and print average + stddev (max: 100)
> +	repeat command and print average + stddev (max: 100). 0 means forever.
>  
>  -B::
>  --big-num::
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index c247fac..b02b3a9 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -87,6 +87,7 @@ static FILE			*output				= NULL;
>  static const char		*pre_cmd			= NULL;
>  static const char		*post_cmd			= NULL;
>  static bool			sync_run			= false;
> +static bool			forever				= false;
>  
>  static volatile int done = 0;
>  
> @@ -94,6 +95,11 @@ struct perf_stat {
>  	struct stats	  res_stats[3];
>  };
>  
> +static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
> +{
> +	memset(evsel->priv, 0, sizeof(struct perf_stat));
> +}
> +
>  static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
>  {
>  	evsel->priv = zalloc(sizeof(struct perf_stat));
> @@ -129,6 +135,22 @@ static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
>  static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
>  static struct stats walltime_nsecs_stats;
>  
> +static void reset_stats(void)
> +{
> +	memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
> +	memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
> +	memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
> +	memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats));
> +	memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats));
> +	memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats));
> +	memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats));
> +	memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats));
> +	memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
> +	memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
> +	memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
> +	memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
> +}
> +
>  static int create_perf_stat_counter(struct perf_evsel *evsel)
>  {
>  	struct perf_event_attr *attr = &evsel->attr;
> @@ -1120,7 +1142,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
>  	OPT_INCR('v', "verbose", &verbose,
>  		    "be more verbose (show counter open errors, etc)"),
>  	OPT_INTEGER('r', "repeat", &run_count,
> -		    "repeat command and print average + stddev (max: 100)"),
> +		    "repeat command and print average + stddev (max: 100, forever: 0)"),
>  	OPT_BOOLEAN('n', "null", &null_run,
>  		    "null run - dont start any counters"),
>  	OPT_INCR('d', "detailed", &detailed_run,
> @@ -1220,8 +1242,12 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
>  
>  	if (!argc && !perf_target__has_task(&target))
>  		usage_with_options(stat_usage, options);
> -	if (run_count <= 0)
> +	if (run_count < 0) {
>  		usage_with_options(stat_usage, options);
> +	} else if (run_count == 0) {
> +		forever = true;
> +		run_count = 1;
> +	}
>  
>  	/* no_aggr, cgroup are for system-wide only */
>  	if ((no_aggr || nr_cgroups) && !perf_target__has_cpu(&target)) {
> @@ -1259,21 +1285,31 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
>  	 * task, but being ignored by perf stat itself:
>  	 */
>  	atexit(sig_atexit);
> -	signal(SIGINT,  skip_signal);
> +	if (!forever)
> +		signal(SIGINT,  skip_signal);
>  	signal(SIGALRM, skip_signal);
>  	signal(SIGABRT, skip_signal);
>  
>  	status = 0;
> -	for (run_idx = 0; run_idx < run_count; run_idx++) {
> +	for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
>  		if (run_count != 1 && verbose)
>  			fprintf(output, "[ perf stat: executing run #%d ... ]\n",
> -				run_idx + 1);
> +					run_idx + 1);
>  
>  		status = run_perf_stat(argc, argv);
> +		if (forever && status != -1) {
> +			print_stat(argc, argv);
> +			list_for_each_entry(pos, &evsel_list->entries, node) {
> +				perf_evsel__reset_stat_priv(pos);
> +				perf_evsel__reset_counts(pos, perf_evsel__nr_cpus(pos));
> +			}
> +			reset_stats();
> +		}
>  	}
>  
> -	if (status != -1)
> +	if (!forever && status != -1)
>  		print_stat(argc, argv);
> +
>  out_free_fd:
>  	list_for_each_entry(pos, &evsel_list->entries, node)
>  		perf_evsel__free_stat_priv(pos);
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index 1b16dd1..0c49e79 100644
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -580,6 +580,12 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
>  	return 0;
>  }
>  
> +void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus)
> +{
> +	memset(evsel->counts, 0, (sizeof(*evsel->counts) +
> +				 (ncpus * sizeof(struct perf_counts_values))));
> +}
> +
>  int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
>  {
>  	evsel->counts = zalloc((sizeof(*evsel->counts) +
> diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
> index 3d2b801..364d820 100644
> --- a/tools/perf/util/evsel.h
> +++ b/tools/perf/util/evsel.h
> @@ -114,6 +114,7 @@ const char *perf_evsel__name(struct perf_evsel *evsel);
>  int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
>  int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
>  int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
> +void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus);
>  void perf_evsel__free_fd(struct perf_evsel *evsel);
>  void perf_evsel__free_id(struct perf_evsel *evsel);
>  void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);

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

* Re: [patch] perf stat: --repeat forever
  2013-02-18 15:04 ` Arnaldo Carvalho de Melo
@ 2013-02-18 17:24   ` Frederik Deweerdt
  0 siblings, 0 replies; 5+ messages in thread
From: Frederik Deweerdt @ 2013-02-18 17:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: a.p.zijlstra, paulus, mingo, linux-kernel

Hi Arnaldo,

On Mon, Feb 18, 2013 at 12:04:44PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Fri, Feb 15, 2013 at 05:28:49PM -0500, Frederik Deweerdt escreveu:
> > Hi,
> > 
> > The following patch causes 'perf stat --repeat 0' to be interpreted as
> > 'forever', displaying the stats for every run.
> > 
> > We act as if a single run was asked, and reset the stats in each
> > iteration. In this mode SIGINT is passed to perf to be able to stop the
> > loop with Ctrl+C.
> 
> It is not applying to my perf/core branch, please take a look at:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux
> 
> branch perf/core
> 
Noted, I'll base the next version based on this branch.

> Also please consider removing the need to specify 0, i.e. I think this
> is possible and shorter:
> 
> # perf stat -a --repeat sleep 1

I'm unsure how to achieve that. I've looked at the different OPT_*
defines, but I can't find one that would do the job. Any pointers?

Thanks,
Frederik

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

* [patch v2] perf stat: --repeat forever
  2013-02-15 22:28 [patch] perf stat: --repeat forever Frederik Deweerdt
  2013-02-18 15:04 ` Arnaldo Carvalho de Melo
@ 2013-03-01 18:02 ` Frederik Deweerdt
  2013-03-21 11:48   ` [tip:perf/core] perf stat: Introduce " tip-bot for Frederik Deweerdt
  1 sibling, 1 reply; 5+ messages in thread
From: Frederik Deweerdt @ 2013-03-01 18:02 UTC (permalink / raw)
  To: acme; +Cc: linux-kernel, a.p.zijlstra, paulus, mingo

Hi,

[This is based on git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux perf/core]

The following patch causes 'perf stat --repeat 0' to be interpreted as
'forever', displaying the stats for every run.

We act as if a single run was asked, and reset the stats in each
iteration. In this mode SIGINT is passed to perf to be able to stop the
loop with Ctrl+C.

Regards,
Frederik


Signed-off-by: Frederik Deweerdt <frederik.deweerdt@gmail.com>

diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index faf4f4f..23e587a 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -52,7 +52,7 @@ OPTIONS
 
 -r::
 --repeat=<n>::
-	repeat command and print average + stddev (max: 100)
+	repeat command and print average + stddev (max: 100). 0 means forever.
 
 -B::
 --big-num::
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 9984876..f59ab78 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -94,6 +94,7 @@ static const char		*pre_cmd			= NULL;
 static const char		*post_cmd			= NULL;
 static bool			sync_run			= false;
 static unsigned int		interval			= 0;
+static bool			forever				= false;
 static struct timespec		ref_time;
 static struct cpu_map		*sock_map;
 
@@ -125,6 +126,11 @@ static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)
 	return perf_evsel__cpus(evsel)->nr;
 }
 
+static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
+{
+	memset(evsel->priv, 0, sizeof(struct perf_stat));
+}
+
 static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
 {
 	evsel->priv = zalloc(sizeof(struct perf_stat));
@@ -173,6 +179,22 @@ static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
 static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
 static struct stats walltime_nsecs_stats;
 
+static void reset_stats(void)
+{
+	memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
+	memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
+	memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
+	memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats));
+	memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats));
+	memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats));
+	memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats));
+	memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats));
+	memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
+	memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
+	memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
+	memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
+}
+
 static int create_perf_stat_counter(struct perf_evsel *evsel)
 {
 	struct perf_event_attr *attr = &evsel->attr;
@@ -1296,7 +1318,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 	OPT_INCR('v', "verbose", &verbose,
 		    "be more verbose (show counter open errors, etc)"),
 	OPT_INTEGER('r', "repeat", &run_count,
-		    "repeat command and print average + stddev (max: 100)"),
+		    "repeat command and print average + stddev (max: 100, forever: 0)"),
 	OPT_BOOLEAN('n', "null", &null_run,
 		    "null run - dont start any counters"),
 	OPT_INCR('d', "detailed", &detailed_run,
@@ -1399,8 +1421,12 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 
 	if (!argc && !perf_target__has_task(&target))
 		usage_with_options(stat_usage, options);
-	if (run_count <= 0)
+	if (run_count < 0) {
 		usage_with_options(stat_usage, options);
+	} else if (run_count == 0) {
+		forever = true;
+		run_count = 1;
+	}
 
 	/* no_aggr, cgroup are for system-wide only */
 	if ((no_aggr || nr_cgroups) && !perf_target__has_cpu(&target)) {
@@ -1457,21 +1483,30 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 	 * task, but being ignored by perf stat itself:
 	 */
 	atexit(sig_atexit);
-	signal(SIGINT,  skip_signal);
+	if (!forever)
+		signal(SIGINT,  skip_signal);
 	signal(SIGCHLD, skip_signal);
 	signal(SIGALRM, skip_signal);
 	signal(SIGABRT, skip_signal);
 
 	status = 0;
-	for (run_idx = 0; run_idx < run_count; run_idx++) {
+	for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
 		if (run_count != 1 && verbose)
 			fprintf(output, "[ perf stat: executing run #%d ... ]\n",
 				run_idx + 1);
 
 		status = run_perf_stat(argc, argv);
+		if (forever && status != -1) {
+			print_stat(argc, argv);
+			list_for_each_entry(pos, &evsel_list->entries, node) {
+				perf_evsel__reset_stat_priv(pos);
+				perf_evsel__reset_counts(pos, perf_evsel__nr_cpus(pos));
+			}
+			reset_stats();
+		}
 	}
 
-	if (status != -1 && !interval)
+	if (!forever && status != -1 && !interval)
 		print_stat(argc, argv);
 out_free_fd:
 	list_for_each_entry(pos, &evsel_list->entries, node) {
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index dc16231..6e55a5f 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -633,6 +633,12 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
 	return 0;
 }
 
+void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus)
+{
+	memset(evsel->counts, 0, (sizeof(*evsel->counts) +
+				 (ncpus * sizeof(struct perf_counts_values))));
+}
+
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
 {
 	evsel->counts = zalloc((sizeof(*evsel->counts) +
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 52021c3..d1eb4da 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -120,6 +120,7 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);
 int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
 int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
+void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus);
 void perf_evsel__free_fd(struct perf_evsel *evsel);
 void perf_evsel__free_id(struct perf_evsel *evsel);
 void perf_evsel__free_counts(struct perf_evsel *evsel);

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

* [tip:perf/core] perf stat: Introduce --repeat forever
  2013-03-01 18:02 ` [patch v2] " Frederik Deweerdt
@ 2013-03-21 11:48   ` tip-bot for Frederik Deweerdt
  0 siblings, 0 replies; 5+ messages in thread
From: tip-bot for Frederik Deweerdt @ 2013-03-21 11:48 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, mingo, frederik.deweerdt, hpa, mingo,
	a.p.zijlstra, frederik.deweerdt, tglx

Commit-ID:  a7e191c376fad084d9f3c7ac89a1f7c47462ebc8
Gitweb:     http://git.kernel.org/tip/a7e191c376fad084d9f3c7ac89a1f7c47462ebc8
Author:     Frederik Deweerdt <frederik.deweerdt@xprog.eu>
AuthorDate: Fri, 1 Mar 2013 13:02:27 -0500
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 15 Mar 2013 14:01:26 -0300

perf stat: Introduce --repeat forever

The following patch causes 'perf stat --repeat 0' to be interpreted as
'forever', displaying the stats for every run.

We act as if a single run was asked, and reset the stats in each
iteration. In this mode SIGINT is passed to perf to be able to stop the
loop with Ctrl+C.

Signed-off-by: Frederik Deweerdt <frederik.deweerdt@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20130301180227.GA24385@ks398093.ip-192-95-24.net
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-stat.txt |  2 +-
 tools/perf/builtin-stat.c              | 45 ++++++++++++++++++++++++++++++----
 tools/perf/util/evsel.c                |  6 +++++
 tools/perf/util/evsel.h                |  1 +
 4 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index faf4f4f..23e587a 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -52,7 +52,7 @@ OPTIONS
 
 -r::
 --repeat=<n>::
-	repeat command and print average + stddev (max: 100)
+	repeat command and print average + stddev (max: 100). 0 means forever.
 
 -B::
 --big-num::
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 69fe6ed..021783a 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -94,6 +94,7 @@ static const char		*pre_cmd			= NULL;
 static const char		*post_cmd			= NULL;
 static bool			sync_run			= false;
 static unsigned int		interval			= 0;
+static bool			forever				= false;
 static struct timespec		ref_time;
 static struct cpu_map		*sock_map;
 
@@ -125,6 +126,11 @@ static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)
 	return perf_evsel__cpus(evsel)->nr;
 }
 
+static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
+{
+	memset(evsel->priv, 0, sizeof(struct perf_stat));
+}
+
 static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
 {
 	evsel->priv = zalloc(sizeof(struct perf_stat));
@@ -173,6 +179,22 @@ static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
 static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
 static struct stats walltime_nsecs_stats;
 
+static void reset_stats(void)
+{
+	memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
+	memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
+	memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
+	memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats));
+	memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats));
+	memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats));
+	memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats));
+	memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats));
+	memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
+	memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
+	memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
+	memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
+}
+
 static int create_perf_stat_counter(struct perf_evsel *evsel)
 {
 	struct perf_event_attr *attr = &evsel->attr;
@@ -1252,7 +1274,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 	OPT_INCR('v', "verbose", &verbose,
 		    "be more verbose (show counter open errors, etc)"),
 	OPT_INTEGER('r', "repeat", &run_count,
-		    "repeat command and print average + stddev (max: 100)"),
+		    "repeat command and print average + stddev (max: 100, forever: 0)"),
 	OPT_BOOLEAN('n', "null", &null_run,
 		    "null run - dont start any counters"),
 	OPT_INCR('d', "detailed", &detailed_run,
@@ -1355,8 +1377,12 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 
 	if (!argc && !perf_target__has_task(&target))
 		usage_with_options(stat_usage, options);
-	if (run_count <= 0)
+	if (run_count < 0) {
 		usage_with_options(stat_usage, options);
+	} else if (run_count == 0) {
+		forever = true;
+		run_count = 1;
+	}
 
 	/* no_aggr, cgroup are for system-wide only */
 	if ((no_aggr || nr_cgroups) && !perf_target__has_cpu(&target)) {
@@ -1413,21 +1439,30 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 	 * task, but being ignored by perf stat itself:
 	 */
 	atexit(sig_atexit);
-	signal(SIGINT,  skip_signal);
+	if (!forever)
+		signal(SIGINT,  skip_signal);
 	signal(SIGCHLD, skip_signal);
 	signal(SIGALRM, skip_signal);
 	signal(SIGABRT, skip_signal);
 
 	status = 0;
-	for (run_idx = 0; run_idx < run_count; run_idx++) {
+	for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
 		if (run_count != 1 && verbose)
 			fprintf(output, "[ perf stat: executing run #%d ... ]\n",
 				run_idx + 1);
 
 		status = run_perf_stat(argc, argv);
+		if (forever && status != -1) {
+			print_stat(argc, argv);
+			list_for_each_entry(pos, &evsel_list->entries, node) {
+				perf_evsel__reset_stat_priv(pos);
+				perf_evsel__reset_counts(pos, perf_evsel__nr_cpus(pos));
+			}
+			reset_stats();
+		}
 	}
 
-	if (status != -1 && !interval)
+	if (!forever && status != -1 && !interval)
 		print_stat(argc, argv);
 out_free_fd:
 	list_for_each_entry(pos, &evsel_list->entries, node) {
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 7fde9fb..1adb824 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -633,6 +633,12 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
 	return 0;
 }
 
+void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus)
+{
+	memset(evsel->counts, 0, (sizeof(*evsel->counts) +
+				 (ncpus * sizeof(struct perf_counts_values))));
+}
+
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
 {
 	evsel->counts = zalloc((sizeof(*evsel->counts) +
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index bf758e5..3f156cc 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -121,6 +121,7 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);
 int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
 int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
+void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus);
 void perf_evsel__free_fd(struct perf_evsel *evsel);
 void perf_evsel__free_id(struct perf_evsel *evsel);
 void perf_evsel__free_counts(struct perf_evsel *evsel);

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

end of thread, other threads:[~2013-03-21 11:50 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-15 22:28 [patch] perf stat: --repeat forever Frederik Deweerdt
2013-02-18 15:04 ` Arnaldo Carvalho de Melo
2013-02-18 17:24   ` Frederik Deweerdt
2013-03-01 18:02 ` [patch v2] " Frederik Deweerdt
2013-03-21 11:48   ` [tip:perf/core] perf stat: Introduce " tip-bot for Frederik Deweerdt

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.