Add "enable_counters" and "disable_counters" function pointers to the
pfm_arch_pmu_info structure. Implement these routines in all of the powerpc
model-specific modules.

enable_counters is called from pfm_arch_start(), and disable_counters is
called from pfm_stop_active(). The existing code from those two routines
was moved to the power5 and ppc32 modules.

Calls to enable_counters are also added to pfm_arch_ctxswin_thread() and
to pfm_arch_intr_unfreeze_pmu().

Signed-off-by: Kevin Corry <[EMAIL PROTECTED]>
Signed-off-by: Carl Love <[EMAIL PROTECTED]>

Index: linux-2.6.21-perfmon1/arch/powerpc/perfmon/perfmon.c
===================================================================
--- linux-2.6.21-perfmon1.orig/arch/powerpc/perfmon/perfmon.c
+++ linux-2.6.21-perfmon1/arch/powerpc/perfmon/perfmon.c
@@ -64,15 +64,11 @@ static void __pfm_get_ovfl_pmds(struct p
 static void pfm_stop_active(struct task_struct *task,
                            struct pfm_context *ctx, struct pfm_event_set *set)
 {
-       unsigned int i, max;
+       struct pfm_arch_pmu_info *arch_info = pfm_pmu_conf->arch_info;
 
-       max = pfm_pmu_conf->max_pmc;
-       /*
-        * clear enable bits
-        */
-       for (i = 0; i < max; i++)
-               if (test_bit(i, set->used_pmcs))
-                       pfm_arch_write_pmc(ctx, i,0);
+       BUG_ON(!arch_info->disable_counters);
+
+       arch_info->disable_counters(set);
 
        if (set->npend_ovfls)
                return;
@@ -105,6 +101,17 @@ int pfm_arch_ctxswout_thread(struct task
 }
 
 /*
+ * Called from pfm_ctxsw
+ */
+void pfm_arch_ctxswin_thread(struct task_struct *task,
+                            struct pfm_context *ctx, struct pfm_event_set *set)
+{
+       struct pfm_arch_pmu_info *arch_info = pfm_pmu_conf->arch_info;
+       BUG_ON(!arch_info->enable_counters);
+       arch_info->enable_counters(set);
+}
+
+/*
  * Called from pfm_stop() and idle notifier
  *
  * Interrupts are masked. Context is locked. Set is the active set.
@@ -155,16 +162,14 @@ void pfm_arch_stop(struct task_struct *t
 void pfm_arch_start(struct task_struct *task,
                    struct pfm_context *ctx, struct pfm_event_set *set)
 {
-       unsigned int i, max_pmc;
+       struct pfm_arch_pmu_info *arch_info = pfm_pmu_conf->arch_info;
 
        if (task != current)
                return;
 
-       max_pmc = pfm_pmu_conf->max_pmc;
+       BUG_ON(!arch_info->enable_counters);
 
-       for (i = 0; i < max_pmc; i++)
-               if (test_bit(i,set->used_pmcs))
-                   pfm_arch_write_pmc(ctx, i, set->pmcs[i]);
+       arch_info->enable_counters(set);
 }
 
 /*
@@ -267,9 +272,12 @@ void pfm_arch_intr_freeze_pmu(struct pfm
  */
 void pfm_arch_intr_unfreeze_pmu(struct pfm_context *ctx)
 {
-       if (!ctx)
-               return;
-       pfm_arch_restore_pmcs(ctx, ctx->active_set);
+       struct pfm_arch_pmu_info *arch_info;
+       if (ctx) {
+               arch_info = pfm_pmu_conf->arch_info;
+               BUG_ON(!arch_info->enable_counters);
+               arch_info->enable_counters(ctx->active_set);
+       }
 }
 
 char *pfm_arch_get_pmu_module_name(void)
Index: linux-2.6.21-perfmon1/arch/powerpc/perfmon/perfmon_cell.c
===================================================================
--- linux-2.6.21-perfmon1.orig/arch/powerpc/perfmon/perfmon_cell.c
+++ linux-2.6.21-perfmon1/arch/powerpc/perfmon/perfmon_cell.c
@@ -269,11 +269,33 @@ static u64 pfm_cell_read_pmd(unsigned in
        return -EINVAL;
 }
 
+/**
+ * pfm_cell_enable_counters
+ *
+ * Just need to turn on the global disable bit in pm_control.
+ **/
+static void pfm_cell_enable_counters(struct pfm_event_set *set)
+{
+       cbe_enable_pm(smp_processor_id());
+}
+
+/**
+ * pfm_cell_disable_counters
+ *
+ * Just need to turn off the global disable bit in pm_control.
+ **/
+static void pfm_cell_disable_counters(struct pfm_event_set *set)
+{
+       cbe_disable_pm(smp_processor_id());
+}
+
 static struct pfm_arch_pmu_info pfm_cell_pmu_info = {
-       .pmu_style = PFM_POWERPC_PMU_CELL,
-       .write_pmc = pfm_cell_write_pmc,
-       .write_pmd = pfm_cell_write_pmd,
-       .read_pmd  = pfm_cell_read_pmd,
+       .pmu_style        = PFM_POWERPC_PMU_CELL,
+       .write_pmc        = pfm_cell_write_pmc,
+       .write_pmd        = pfm_cell_write_pmd,
+       .read_pmd         = pfm_cell_read_pmd,
+       .enable_counters  = pfm_cell_enable_counters,
+       .disable_counters = pfm_cell_disable_counters,
 };
 
 static struct pfm_pmu_config pfm_cell_pmu_conf = {
Index: linux-2.6.21-perfmon1/arch/powerpc/perfmon/perfmon_power5.c
===================================================================
--- linux-2.6.21-perfmon1.orig/arch/powerpc/perfmon/perfmon_power5.c
+++ linux-2.6.21-perfmon1/arch/powerpc/perfmon/perfmon_power5.c
@@ -146,11 +146,45 @@ static u64 pfm_power5_read_pmd(unsigned 
        }
 }
 
+/**
+ * pfm_power5_enable_counters
+ *
+ * Just need to load the current values into the control registers.
+ **/
+static void pfm_power5_enable_counters(struct pfm_event_set *set)
+{
+       unsigned int i, max_pmc;
+
+       max_pmc = pfm_pmu_conf->max_pmc;
+
+       for (i = 0; i < max_pmc; i++)
+               if (test_bit(i, set->used_pmcs))
+                       pfm_power5_write_pmc(i, set->pmcs[i]);
+}
+
+/**
+ * pfm_power5_disable_counters
+ *
+ * Just need to zero all the control registers.
+ **/
+static void pfm_power5_disable_counters(struct pfm_event_set *set)
+{
+       unsigned int i, max;
+
+       max = pfm_pmu_conf->max_pmc;
+
+       for (i = 0; i < max; i++)
+               if (test_bit(i, set->used_pmcs))
+                       pfm_power5_write_pmc(i, 0);
+}
+
 struct pfm_arch_pmu_info pfm_power5_pmu_info = {
-       .pmu_style = PFM_POWERPC_PMU_POWER5,
-       .write_pmc = pfm_power5_write_pmc,
-       .write_pmd = pfm_power5_write_pmd,
-       .read_pmd  = pfm_power5_read_pmd,
+       .pmu_style        = PFM_POWERPC_PMU_POWER5,
+       .write_pmc        = pfm_power5_write_pmc,
+       .write_pmd        = pfm_power5_write_pmd,
+       .read_pmd         = pfm_power5_read_pmd,
+       .enable_counters  = pfm_power5_enable_counters,
+       .disable_counters = pfm_power5_disable_counters,
 };
 
 /*
Index: linux-2.6.21-perfmon1/arch/powerpc/perfmon/perfmon_ppc32.c
===================================================================
--- linux-2.6.21-perfmon1.orig/arch/powerpc/perfmon/perfmon_ppc32.c
+++ linux-2.6.21-perfmon1/arch/powerpc/perfmon/perfmon_ppc32.c
@@ -240,11 +240,45 @@ static u64 pfm_ppc32_read_pmd(unsigned i
        }
 }
 
+/**
+ * pfm_ppc32_enable_counters
+ *
+ * Just need to load the current values into the control registers.
+ **/
+static void pfm_ppc32_enable_counters(struct pfm_event_set *set)
+{
+       unsigned int i, max_pmc;
+
+       max_pmc = pfm_pmu_conf->max_pmc;
+
+       for (i = 0; i < max_pmc; i++)
+               if (test_bit(i, set->used_pmcs))
+                       pfm_ppc32_write_pmc(i, set->pmcs[i]);
+}
+
+/**
+ * pfm_ppc32_disable_counters
+ *
+ * Just need to zero all the control registers.
+ **/
+static void pfm_ppc32_disable_counters(struct pfm_event_set *set)
+{
+       unsigned int i, max;
+
+       max = pfm_pmu_conf->max_pmc;
+
+       for (i = 0; i < max; i++)
+               if (test_bit(i, set->used_pmcs))
+                       pfm_ppc32_write_pmc(ctx, 0);
+}
+
 struct pfm_arch_pmu_info pfm_ppc32_pmu_info = {
-       .pmu_style = PFM_POWERPC_PMU_NONE,
-       .write_pmc = pfm_ppc32_write_pmc,
-       .write_pmd = pfm_ppc32_write_pmd,
-       .read_pmd  = pfm_ppc32_read_pmd,
+       .pmu_style        = PFM_POWERPC_PMU_NONE,
+       .write_pmc        = pfm_ppc32_write_pmc,
+       .write_pmd        = pfm_ppc32_write_pmd,
+       .read_pmd         = pfm_ppc32_read_pmd,
+       .enable_counters  = pfm_ppc32_enable_counters,
+       .disable_counters = pfm_ppc32_disable_counters,
 };
 
 static struct pfm_pmu_config pfm_ppc32_pmu_conf = {
Index: linux-2.6.21-perfmon1/include/asm-powerpc/perfmon.h
===================================================================
--- linux-2.6.21-perfmon1.orig/include/asm-powerpc/perfmon.h
+++ linux-2.6.21-perfmon1/include/asm-powerpc/perfmon.h
@@ -49,6 +49,9 @@ struct pfm_arch_pmu_info {
        void (*write_pmd)(unsigned int cnum, u64 value);
 
        u64 (*read_pmd)(unsigned int cnum);
+
+       void (*enable_counters)(struct pfm_event_set *set);
+       void (*disable_counters)(struct pfm_event_set *set);
 };
 
 #ifdef CONFIG_PPC32
@@ -142,15 +145,12 @@ static inline void pfm_arch_ctxswin_sys(
                                        struct pfm_event_set *set)
 {}
 
-static inline void pfm_arch_ctxswin_thread(struct task_struct *task,
-                                          struct pfm_context *ctx,
-                                          struct pfm_event_set *set)
-{}
-
 void pfm_arch_init_percpu(void);
 int  pfm_arch_is_monitoring_active(struct pfm_context *ctx);
 int  pfm_arch_ctxswout_thread(struct task_struct *task, struct pfm_context 
*ctx,
                              struct pfm_event_set *set);
+void pfm_arch_ctxswin_thread(struct task_struct *task, struct pfm_context *ctx,
+                            struct pfm_event_set *set);
 void pfm_arch_stop(struct task_struct *task, struct pfm_context *ctx,
                          struct pfm_event_set *set);
 void pfm_arch_start(struct task_struct *task, struct pfm_context *ctx,
_______________________________________________
perfmon mailing list
[email protected]
http://www.hpl.hp.com/hosted/linux/mail-archives/perfmon/

Reply via email to