Patchwork [1/6] perf_counter: powerpc: Enable use of software counters on 32-bit powerpc

login
register
mail settings
Submitter Paul Mackerras
Date June 17, 2009, 11:50 a.m.
Message ID <19000.55404.103840.393470@cargo.ozlabs.ibm.com>
Download mbox | patch
Permalink /patch/28779/
State Accepted, archived
Headers show

Comments

Paul Mackerras - June 17, 2009, 11:50 a.m.
This enables the perf_counter subsystem on 32-bit powerpc.  Since we
don't have any support for hardware counters on 32-bit powerpc yet,
only software counters can be used.

Besides selecting HAVE_PERF_COUNTERS for 32-bit powerpc as well as
64-bit, the main thing this does is add an implementation of
set_perf_counter_pending().  This needs to arrange for
perf_counter_do_pending() to be called when interrupts are enabled.
Rather than add code to local_irq_restore as 64-bit does, the 32-bit
set_perf_counter_pending() generates an interrupt by setting the
decrementer to 1 so that a decrementer interrupt will become pending
in 1 or 2 timebase ticks (if a decrementer interrupt isn't already
pending).  When interrupts are enabled, timer_interrupt() will be
called, and some new code in there calls perf_counter_do_pending().
We use a per-cpu array of flags to indicate whether we need to call
perf_counter_do_pending() or not.

This introduces a couple of new Kconfig symbols: PPC_HAVE_PMU_SUPPORT,
which is selected by processor families for which we have hardware PMU
support (currently only PPC64), and PPC_PERF_CTRS, which enables the
powerpc-specific perf_counter back-end.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
This depends on the generic atomic64_t patches, which are now in
Linus' tree.  Ingo, if you're putting these in, please pull Linus'
tree in first.

 arch/powerpc/Kconfig                    |    1 +
 arch/powerpc/include/asm/hw_irq.h       |    5 ++++-
 arch/powerpc/include/asm/perf_counter.h |   10 ++++++++--
 arch/powerpc/kernel/Makefile            |    6 +++---
 arch/powerpc/kernel/time.c              |   25 +++++++++++++++++++++++++
 arch/powerpc/platforms/Kconfig.cputype  |   11 ++++++++++-
 6 files changed, 51 insertions(+), 7 deletions(-)
Ingo Molnar - June 17, 2009, 12:04 p.m.
* Paul Mackerras <paulus@samba.org> wrote:

> This depends on the generic atomic64_t patches, which are now in 
> Linus' tree.  Ingo, if you're putting these in, please pull Linus' 
> tree in first.

yes, i already did that earlier today - so all should be fine with 
the lib/atomic64.c dependency.

	Ingo
Kumar Gala - June 17, 2009, 2:10 p.m.
On Jun 17, 2009, at 6:50 AM, Paul Mackerras wrote:

> diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/ 
> platforms/Kconfig.cputype
> index cca6b4f..dd9f3ec 100644
> --- a/arch/powerpc/platforms/Kconfig.cputype
> +++ b/arch/powerpc/platforms/Kconfig.cputype
> @@ -1,7 +1,7 @@
> config PPC64
> 	bool "64-bit kernel"
> 	default n
> -	select HAVE_PERF_COUNTERS
> +	select PPC_HAVE_PMU_SUPPORT
> 	help
> 	  This option selects whether a 32-bit or a 64-bit kernel
> 	  will be built.
> @@ -243,6 +243,15 @@ config VIRT_CPU_ACCOUNTING
>
> 	  If in doubt, say Y here.
>
> +config PPC_HAVE_PMU_SUPPORT
> +       bool

what does this mean?

> +
> +config PPC_PERF_CTRS
> +       def_bool y
> +       depends on PERF_COUNTERS && PPC_HAVE_PMU_SUPPORT
> +       help
> +         This enables the powerpc-specific perf_counter back-end.

Can we distinguish between the two different architected perf counters  
programming models to start with.  Maybe something like:

PPC_BOOK3S_PERF_CTRS and PPC_BOOK3E_PERF_CTRS (or  
PPC_SERVER_PERF_CTRS / PPC_EMB_PERF_CTRS)


>
> +
> config SMP
> 	depends on PPC_STD_MMU || FSL_BOOKE
> 	bool "Symmetric multi-processing support"
> -- 
> 1.6.0.4
>
Ingo Molnar - June 17, 2009, 2:21 p.m.
* Paul Mackerras <paulus@samba.org> wrote:

> This depends on the generic atomic64_t patches, which are now in 
> Linus' tree.  Ingo, if you're putting these in, please pull Linus' 
> tree in first.

Note, i've created a new branch, tip:perfcounters/powerpc, so we can 
keep these things separate and Ben can pull them too. I see there 
was some review feedback - do you want to send a v2 version perhaps?

	Ingo
Kumar Gala - June 17, 2009, 2:24 p.m.
On Jun 17, 2009, at 9:21 AM, Ingo Molnar wrote:

>
> * Paul Mackerras <paulus@samba.org> wrote:
>
>> This depends on the generic atomic64_t patches, which are now in
>> Linus' tree.  Ingo, if you're putting these in, please pull Linus'
>> tree in first.
>
> Note, i've created a new branch, tip:perfcounters/powerpc, so we can
> keep these things separate and Ben can pull them too. I see there
> was some review feedback - do you want to send a v2 version perhaps?

Out of interest, is the intent to try and get these changes into .31?   
I ask because I want to know if I should try to find time to add  
support for the FSL embedded perfmon ASAP or not.

- k
Ingo Molnar - June 17, 2009, 2:27 p.m.
* Kumar Gala <galak@kernel.crashing.org> wrote:

> On Jun 17, 2009, at 9:21 AM, Ingo Molnar wrote:
>
>> * Paul Mackerras <paulus@samba.org> wrote:
>>
>>> This depends on the generic atomic64_t patches, which are now in 
>>> Linus' tree.  Ingo, if you're putting these in, please pull 
>>> Linus' tree in first.
>>
>> Note, i've created a new branch, tip:perfcounters/powerpc, so we 
>> can keep these things separate and Ben can pull them too. I see 
>> there was some review feedback - do you want to send a v2 version 
>> perhaps?
>
> Out of interest, is the intent to try and get these changes into 
> .31?  I ask because I want to know if I should try to find time to 
> add support for the FSL embedded perfmon ASAP or not.

I think it would be nice to have more platform support in .31. 
Perfcounters is a brand-new feature so there's no risk of 
regression. In the end it will depend on Linus to pull of course, 
and BenH can veto it too if he'd like no more PowerPC changes in 
this cycle. Worst-case it's all .32 material.

	Ingo
Paul Mackerras - June 17, 2009, 11:22 p.m.
Kumar Gala writes:

> On Jun 17, 2009, at 6:50 AM, Paul Mackerras wrote:

> > +config PPC_HAVE_PMU_SUPPORT
> > +       bool
> 
> what does this mean?

At the moment it means that arch/powerpc/kernel/perf_counters.c works
for at least some processors in the selected processor family.

> > +
> > +config PPC_PERF_CTRS
> > +       def_bool y
> > +       depends on PERF_COUNTERS && PPC_HAVE_PMU_SUPPORT
> > +       help
> > +         This enables the powerpc-specific perf_counter back-end.
> 
> Can we distinguish between the two different architected perf counters  
> programming models to start with.  Maybe something like:
> 
> PPC_BOOK3S_PERF_CTRS and PPC_BOOK3E_PERF_CTRS (or  
> PPC_SERVER_PERF_CTRS / PPC_EMB_PERF_CTRS)

We can do that once we have code to support the Freescale embedded PMU
and we know how much of arch/powerpc/kernel/perf_counters.c is or
isn't useful there.  We don't have to get to the final state in one
patch.  I'd rather put this patch in as-is and then see a patch series
that adds the Freescale embedded PMU support and makes whatever
Kconfig changes are necessary later.

Paul.
Paul Mackerras - June 17, 2009, 11:27 p.m.
Ingo Molnar writes:

> Note, i've created a new branch, tip:perfcounters/powerpc, so we can 
> keep these things separate and Ben can pull them too. I see there 
> was some review feedback - do you want to send a v2 version perhaps?

Kumar's comments seemed to me to be wanting changes to accommodate
code that doesn't exist yet, so I think those changes should be done
later when that code exists and we know exactly what is needed.  So
the current patches are fine as-is IMO.

Paul.
Ingo Molnar - June 18, 2009, 9:04 a.m.
* Paul Mackerras <paulus@samba.org> wrote:

> Ingo Molnar writes:
> 
> > Note, i've created a new branch, tip:perfcounters/powerpc, so we can 
> > keep these things separate and Ben can pull them too. I see there 
> > was some review feedback - do you want to send a v2 version perhaps?
> 
> Kumar's comments seemed to me to be wanting changes to accommodate 
> code that doesn't exist yet, so I think those changes should be 
> done later when that code exists and we know exactly what is 
> needed.  So the current patches are fine as-is IMO.

ok - will queue them up.

	Ingo
Benjamin Herrenschmidt - June 18, 2009, 11:01 p.m.
On Wed, 2009-06-17 at 16:21 +0200, Ingo Molnar wrote:
> > This depends on the generic atomic64_t patches, which are now in 
> > Linus' tree.  Ingo, if you're putting these in, please pull Linus' 
> > tree in first.
> 
> Note, i've created a new branch, tip:perfcounters/powerpc, so we can 
> keep these things separate and Ben can pull them too. I see there 
> was some review feedback - do you want to send a v2 version perhaps?

At this stage, I'm happy for you to push them. I was thinking about
moving the files around but that can wait. No serious comments on the
patches themselves on my side.

Cheers
Ben
Benjamin Herrenschmidt - June 18, 2009, 11:03 p.m.
On Wed, 2009-06-17 at 16:27 +0200, Ingo Molnar wrote:
> I think it would be nice to have more platform support in .31. 
> Perfcounters is a brand-new feature so there's no risk of 
> regression. In the end it will depend on Linus to pull of course, 
> and BenH can veto it too if he'd like no more PowerPC changes in 
> this cycle. Worst-case it's all .32 material.

There have been little PowerPC changes in this cycle and I agree
with you on that it's a nice feature to have with little risk of
regression.

In fact, I also have an up-to-date (and hopefully working)
irqtrace/lockdep patch for 32-bit powerpc (we only do 64-bit right now)
that I'm considering merging this time around, the benefit it brings is
worth the risk I believe.

Cheers,
Ben.
Ingo Molnar - June 20, 2009, 10:32 a.m.
* Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:

> On Wed, 2009-06-17 at 16:27 +0200, Ingo Molnar wrote:
> > I think it would be nice to have more platform support in .31. 
> > Perfcounters is a brand-new feature so there's no risk of 
> > regression. In the end it will depend on Linus to pull of course, 
> > and BenH can veto it too if he'd like no more PowerPC changes in 
> > this cycle. Worst-case it's all .32 material.
> 
> There have been little PowerPC changes in this cycle and I agree 
> with you on that it's a nice feature to have with little risk of 
> regression.

Ok - thanks - i'll push it to Linus probably later today.

> In fact, I also have an up-to-date (and hopefully working) 
> irqtrace/lockdep patch for 32-bit powerpc (we only do 64-bit right 
> now) that I'm considering merging this time around, the benefit it 
> brings is worth the risk I believe.

Nice :-)

	Ingo

Patch

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9fb344d..bf6cedf 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -126,6 +126,7 @@  config PPC
 	select HAVE_OPROFILE
 	select HAVE_SYSCALL_WRAPPERS if PPC64
 	select GENERIC_ATOMIC64 if PPC32
+	select HAVE_PERF_COUNTERS
 
 config EARLY_PRINTK
 	bool
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index 10a642d..867ab8e 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -131,6 +131,8 @@  static inline int irqs_disabled_flags(unsigned long flags)
 struct irq_chip;
 
 #ifdef CONFIG_PERF_COUNTERS
+
+#ifdef CONFIG_PPC64
 static inline unsigned long test_perf_counter_pending(void)
 {
 	unsigned long x;
@@ -154,8 +156,9 @@  static inline void clear_perf_counter_pending(void)
 		"r" (0),
 		"i" (offsetof(struct paca_struct, perf_counter_pending)));
 }
+#endif /* CONFIG_PPC64 */
 
-#else
+#else  /* CONFIG_PERF_COUNTERS */
 
 static inline unsigned long test_perf_counter_pending(void)
 {
diff --git a/arch/powerpc/include/asm/perf_counter.h b/arch/powerpc/include/asm/perf_counter.h
index b398a84..2c2d9f6 100644
--- a/arch/powerpc/include/asm/perf_counter.h
+++ b/arch/powerpc/include/asm/perf_counter.h
@@ -57,11 +57,17 @@  extern struct power_pmu *ppmu;
 
 struct pt_regs;
 extern unsigned long perf_misc_flags(struct pt_regs *regs);
-#define perf_misc_flags(regs)	perf_misc_flags(regs)
-
 extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
 
 /*
+ * Only override the default definitions in include/linux/perf_counter.h
+ * if we have hardware PMU support.
+ */
+#ifdef CONFIG_PPC_PERF_CTRS
+#define perf_misc_flags(regs)	perf_misc_flags(regs)
+#endif
+
+/*
  * The power_pmu.get_constraint function returns a 64-bit value and
  * a 64-bit mask that express the constraints between this event and
  * other events.
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 612b0c4..c5f93f0 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -95,9 +95,9 @@  obj64-$(CONFIG_AUDIT)		+= compat_audit.o
 
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
-obj-$(CONFIG_PERF_COUNTERS)	+= perf_counter.o power4-pmu.o ppc970-pmu.o \
-				   power5-pmu.o power5+-pmu.o power6-pmu.o \
-				   power7-pmu.o
+obj-$(CONFIG_PPC_PERF_CTRS)	+= perf_counter.o
+obj64-$(CONFIG_PPC_PERF_CTRS)	+= power4-pmu.o ppc970-pmu.o power5-pmu.o \
+				   power5+-pmu.o power6-pmu.o power7-pmu.o
 
 obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o
 
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 15391c2..eae4511 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -53,6 +53,7 @@ 
 #include <linux/posix-timers.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
+#include <linux/perf_counter.h>
 
 #include <asm/io.h>
 #include <asm/processor.h>
@@ -525,6 +526,26 @@  void __init iSeries_time_init_early(void)
 }
 #endif /* CONFIG_PPC_ISERIES */
 
+#if defined(CONFIG_PERF_COUNTERS) && defined(CONFIG_PPC32)
+DEFINE_PER_CPU(u8, perf_counter_pending);
+
+void set_perf_counter_pending(void)
+{
+	get_cpu_var(perf_counter_pending) = 1;
+	set_dec(1);
+	put_cpu_var(perf_counter_pending);
+}
+
+#define test_perf_counter_pending()	__get_cpu_var(perf_counter_pending)
+#define clear_perf_counter_pending()	__get_cpu_var(perf_counter_pending) = 0
+
+#else  /* CONFIG_PERF_COUNTERS && CONFIG_PPC32 */
+
+#define test_perf_counter_pending()	0
+#define clear_perf_counter_pending()
+
+#endif /* CONFIG_PERF_COUNTERS && CONFIG_PPC32 */
+
 /*
  * For iSeries shared processors, we have to let the hypervisor
  * set the hardware decrementer.  We set a virtual decrementer
@@ -551,6 +572,10 @@  void timer_interrupt(struct pt_regs * regs)
 	set_dec(DECREMENTER_MAX);
 
 #ifdef CONFIG_PPC32
+	if (test_perf_counter_pending()) {
+		clear_perf_counter_pending();
+		perf_counter_do_pending();
+	}
 	if (atomic_read(&ppc_n_lost_interrupts) != 0)
 		do_IRQ(regs);
 #endif
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index cca6b4f..dd9f3ec 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -1,7 +1,7 @@ 
 config PPC64
 	bool "64-bit kernel"
 	default n
-	select HAVE_PERF_COUNTERS
+	select PPC_HAVE_PMU_SUPPORT
 	help
 	  This option selects whether a 32-bit or a 64-bit kernel
 	  will be built.
@@ -243,6 +243,15 @@  config VIRT_CPU_ACCOUNTING
 
 	  If in doubt, say Y here.
 
+config PPC_HAVE_PMU_SUPPORT
+       bool
+
+config PPC_PERF_CTRS
+       def_bool y
+       depends on PERF_COUNTERS && PPC_HAVE_PMU_SUPPORT
+       help
+         This enables the powerpc-specific perf_counter back-end.
+
 config SMP
 	depends on PPC_STD_MMU || FSL_BOOKE
 	bool "Symmetric multi-processing support"