2009-07-16 02:08:52

by Hitoshi Mitake

[permalink] [raw]
Subject: [PATCH][RFC] Adding transition of CPU frequency counting support to perfcounters


Hi,

I'm trying to add transition of CPU frequency counting support to perfcounters.
If perf can count freq transition, this will be more useful
because frequencies of CPUs are dynamic things today.
And there's no way to count freq transitions per process level.

But I have a question.
I copied the way of sw-events already exist such as migration or page-fault.
But like this,

% perf stat emacs

Performance counter stats for 'emacs':

1324.294227 task-clock-msecs # 0.704 CPUs
1980 context-switches # 0.001 M/sec
30 CPU-migrations # 0.000 M/sec
42986 page-faults # 0.032 M/sec
0 cpufreq-up # 0.000 M/sec
^^^^^^^^^^
0 cpufreq-down # 0.000 M/sec
^^^^^^^^^^^^
4057387374 cycles # 3063.811 M/sec
4767004447 instructions # 1.175 IPC
20687483 cache-references # 15.622 M/sec
5103528 cache-misses # 3.854 M/sec

1.880587959 seconds time elapsed

perf said there's no freq transition.
But I checked there are some transitions with cpufreq-info.

Can you find something bad in this patch?
I'll continue to try implementing.
If you find some bad points, I'd like to hear..

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index b90eda8..805eee2 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -28,6 +28,7 @@
#include <linux/cpu.h>
#include <linux/completion.h>
#include <linux/mutex.h>
+#include <linux/perf_counter.h>

#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, \
"cpufreq-core", msg)
@@ -356,6 +357,12 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
CPUFREQ_POSTCHANGE, freqs);
if (likely(policy) && likely(policy->cpu == freqs->cpu))
policy->cur = freqs->new;
+ if (freqs->new > freqs->old)
+ perf_swcounter_event(PERF_COUNT_SW_CPUFREQ_UP,
+ 1, 0, NULL, 0);
+ else
+ perf_swcounter_event(PERF_COUNT_SW_CPUFREQ_DOWN,
+ 1, 0, NULL, 0);
break;
}
}
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
index 5e970c7..8f93277 100644
--- a/include/linux/perf_counter.h
+++ b/include/linux/perf_counter.h
@@ -102,6 +102,8 @@ enum perf_sw_ids {
PERF_COUNT_SW_CPU_MIGRATIONS = 4,
PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
+ PERF_COUNT_SW_CPUFREQ_UP = 7,
+ PERF_COUNT_SW_CPUFREQ_DOWN = 8,

PERF_COUNT_SW_MAX, /* non-ABI */
};
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index a641eb7..d358509 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -3754,6 +3754,9 @@ static const struct pmu *sw_perf_counter_init(struct perf_counter *counter)
case PERF_COUNT_SW_PAGE_FAULTS_MAJ:
case PERF_COUNT_SW_CONTEXT_SWITCHES:
case PERF_COUNT_SW_CPU_MIGRATIONS:
+ case PERF_COUNT_SW_CPUFREQ_UP:
+ case PERF_COUNT_SW_CPUFREQ_DOWN:
+
if (!counter->parent) {
atomic_inc(&perf_swcounter_enabled[event]);
counter->destroy = sw_perf_counter_destroy;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 27921a8..dbf7969 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -52,6 +52,8 @@ static struct perf_counter_attr default_attrs[] = {
{ .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES},
{ .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS },
{ .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS },
+ { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPUFREQ_UP },
+ { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPUFREQ_DOWN },

{ .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES },
{ .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS },
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 5184959..d83fb36 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -38,6 +38,8 @@ static struct event_symbol event_symbols[] = {
{ CSW(PAGE_FAULTS_MAJ), "major-faults", "" },
{ CSW(CONTEXT_SWITCHES), "context-switches", "cs" },
{ CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" },
+ { CSW(CPUFREQ_UP), "cpufreq-up", "" },
+ { CSW(CPUFREQ_DOWN), "cpufreq-down", "" },
};

#define __PERF_COUNTER_FIELD(config, name) \
@@ -66,6 +68,8 @@ static char *sw_event_names[] = {
"CPU-migrations",
"minor-faults",
"major-faults",
+ "cpufreq-up",
+ "cpufreq-down",
};

#define MAX_ALIASES 8


2009-07-18 09:32:17

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH][RFC] Adding transition of CPU frequency counting support to perfcounters


* Hitoshi Mitake <[email protected]> wrote:

> Hi,
>
> I'm trying to add transition of CPU frequency counting support to perfcounters.
> If perf can count freq transition, this will be more useful
> because frequencies of CPUs are dynamic things today.
> And there's no way to count freq transitions per process level.
>
> But I have a question.
> I copied the way of sw-events already exist such as migration or page-fault.
> But like this,
>
> % perf stat emacs
>
> Performance counter stats for 'emacs':
>
> 1324.294227 task-clock-msecs # 0.704 CPUs
> 1980 context-switches # 0.001 M/sec
> 30 CPU-migrations # 0.000 M/sec
> 42986 page-faults # 0.032 M/sec
> 0 cpufreq-up # 0.000 M/sec
> ^^^^^^^^^^
> 0 cpufreq-down # 0.000 M/sec
> ^^^^^^^^^^^^
> 4057387374 cycles # 3063.811 M/sec
> 4767004447 instructions # 1.175 IPC
> 20687483 cache-references # 15.622 M/sec
> 5103528 cache-misses # 3.854 M/sec
>
> 1.880587959 seconds time elapsed
>
> perf said there's no freq transition.
> But I checked there are some transitions with cpufreq-info.
>
> Can you find something bad in this patch?
> I'll continue to try implementing.
> If you find some bad points, I'd like to hear..

> + if (freqs->new > freqs->old)
> + perf_swcounter_event(PERF_COUNT_SW_CPUFREQ_UP,
> + 1, 0, NULL, 0);
> + else
> + perf_swcounter_event(PERF_COUNT_SW_CPUFREQ_DOWN,
> + 1, 0, NULL, 0);

Could you try:

perf stat -a sleep 60

while you do your emacs run that toggles cpufreq events? This makes
sure all transitions are counted, regardless of which context
triggers it. Do you still get zero counts this way?

Ingo

2009-07-18 14:11:43

by Hitoshi Mitake

[permalink] [raw]
Subject: Re: [PATCH][RFC] Adding transition of CPU frequency counting support to perfcounters

From: Ingo Molnar <[email protected]>
Subject: Re: [PATCH][RFC] Adding transition of CPU frequency counting support to perfcounters
Date: Sat, 18 Jul 2009 11:31:15 +0200

>
> * Hitoshi Mitake <[email protected]> wrote:
>
> > Hi,
> >
> > I'm trying to add transition of CPU frequency counting support to perfcounters.
> > If perf can count freq transition, this will be more useful
> > because frequencies of CPUs are dynamic things today.
> > And there's no way to count freq transitions per process level.
> >
> > But I have a question.
> > I copied the way of sw-events already exist such as migration or page-fault.
> > But like this,
> >
> > % perf stat emacs
> >
> > Performance counter stats for 'emacs':
> >
> > 1324.294227 task-clock-msecs # 0.704 CPUs
> > 1980 context-switches # 0.001 M/sec
> > 30 CPU-migrations # 0.000 M/sec
> > 42986 page-faults # 0.032 M/sec
> > 0 cpufreq-up # 0.000 M/sec
> > ^^^^^^^^^^
> > 0 cpufreq-down # 0.000 M/sec
> > ^^^^^^^^^^^^
> > 4057387374 cycles # 3063.811 M/sec
> > 4767004447 instructions # 1.175 IPC
> > 20687483 cache-references # 15.622 M/sec
> > 5103528 cache-misses # 3.854 M/sec
> >
> > 1.880587959 seconds time elapsed
> >
> > perf said there's no freq transition.
> > But I checked there are some transitions with cpufreq-info.
> >
> > Can you find something bad in this patch?
> > I'll continue to try implementing.
> > If you find some bad points, I'd like to hear..
>
> > + if (freqs->new > freqs->old)
> > + perf_swcounter_event(PERF_COUNT_SW_CPUFREQ_UP,
> > + 1, 0, NULL, 0);
> > + else
> > + perf_swcounter_event(PERF_COUNT_SW_CPUFREQ_DOWN,
> > + 1, 0, NULL, 0);
>
> Could you try:
>
> perf stat -a sleep 60
>
> while you do your emacs run that toggles cpufreq events? This makes
> sure all transitions are counted, regardless of which context
> triggers it. Do you still get zero counts this way?

Oh, my perf could count cpufreq events!
Thanks for your nice advice!

% perf stat -a sleep 60

Performance counter stats for 'sleep 60':

479088.075595 task-clock-msecs # 7.984 CPUs
199080 context-switches # 0.000 M/sec
19584 CPU-migrations # 0.000 M/sec
322978 page-faults # 0.001 M/sec
29 cpufreq-up # 0.000 M/sec
42 cpufreq-down # 0.000 M/sec
73703367828 cycles # 153.841 M/sec
52005203450 instructions # 0.706 IPC
209762467 cache-references # 0.438 M/sec
84916856 cache-misses # 0.177 M/sec

60.009508200 seconds time elapsed

And I'm using ondemand governor now,
so kernel thread [kondemand] context causes freq transition.
I didn't notice that...

Could you merge this patch?
Can I send this patch with descriptions and Signed-off-by?

2009-07-18 16:09:28

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH][RFC] Adding transition of CPU frequency counting support to perfcounters

On Sat, 2009-07-18 at 23:11 +0900, [email protected] wrote:
>
> Oh, my perf could count cpufreq events!
> Thanks for your nice advice!
>
> % perf stat -a sleep 60
>
> Performance counter stats for 'sleep 60':
>
> 479088.075595 task-clock-msecs # 7.984 CPUs
> 199080 context-switches # 0.000 M/sec
> 19584 CPU-migrations # 0.000 M/sec
> 322978 page-faults # 0.001 M/sec
> 29 cpufreq-up # 0.000 M/sec
> 42 cpufreq-down # 0.000 M/sec
> 73703367828 cycles # 153.841 M/sec
> 52005203450 instructions # 0.706 IPC
> 209762467 cache-references # 0.438 M/sec
> 84916856 cache-misses # 0.177 M/sec
>
> 60.009508200 seconds time elapsed
>
> And I'm using ondemand governor now,
> so kernel thread [kondemand] context causes freq transition.
> I didn't notice that...
>
> Could you merge this patch?
> Can I send this patch with descriptions and Signed-off-by?

Why, what is the usecase?

2009-07-21 01:47:01

by Hitoshi Mitake

[permalink] [raw]
Subject: Re: [PATCH][RFC] Adding transition of CPU frequency counting support to perfcounters

From: Peter Zijlstra <[email protected]>
Subject: Re: [PATCH][RFC] Adding transition of CPU frequency counting support to perfcounters
Date: Sat, 18 Jul 2009 18:09:15 +0200

> On Sat, 2009-07-18 at 23:11 +0900, [email protected] wrote:
> >
> > Oh, my perf could count cpufreq events!
> > Thanks for your nice advice!
> >
> > % perf stat -a sleep 60
> >
> > Performance counter stats for 'sleep 60':
> >
> > 479088.075595 task-clock-msecs # 7.984 CPUs
> > 199080 context-switches # 0.000 M/sec
> > 19584 CPU-migrations # 0.000 M/sec
> > 322978 page-faults # 0.001 M/sec
> > 29 cpufreq-up # 0.000 M/sec
> > 42 cpufreq-down # 0.000 M/sec
> > 73703367828 cycles # 153.841 M/sec
> > 52005203450 instructions # 0.706 IPC
> > 209762467 cache-references # 0.438 M/sec
> > 84916856 cache-misses # 0.177 M/sec
> >
> > 60.009508200 seconds time elapsed
> >
> > And I'm using ondemand governor now,
> > so kernel thread [kondemand] context causes freq transition.
> > I didn't notice that...
> >
> > Could you merge this patch?
> > Can I send this patch with descriptions and Signed-off-by?
>
> Why, what is the usecase?
>
>

Hmm, I considered, and I noticed that this patch makes no sense.
Because my first purpose "collecting CPU freq transitions per process level"
is completely nonsense. CPU freq transitions are global things, not one of processes.

In either case, "up" and "down" are too poor information.
At least freqs of each time should be recorded.

Sorry, please disregard this patch.