Hello,Attached is a patch for Power which implements the IRQ resend logic, and also incorporates a fix for when MASKING is enabled, as Stephane requested.
This patch should work for later POWER4 chips through POWER6 chips which have the PMAO bit in the MMCR0 register. I haven't yet figured out how to resend an IRQ for early POWER4, and PPC970, but since we don't have support in yet for PPC970, this limitation will only affect early POWER4 chips.
Please let me know if you see any problems with this patch. Thanks for your consideration. - Corey -- Corey Ashford Software Engineer IBM Linux Technology Center, Linux Toolchain Beaverton, OR 503-578-3507 [EMAIL PROTECTED]
diff --git a/arch/powerpc/perfmon/perfmon.c b/arch/powerpc/perfmon/perfmon.c index 17a45fd..b1197d9 100644 --- a/arch/powerpc/perfmon/perfmon.c +++ b/arch/powerpc/perfmon/perfmon.c @@ -62,6 +62,9 @@ int pfm_arch_ctxswout_thread(struct task_struct *task, struct pfm_context *ctx) */ ctx->active_set->priv_flags |= PFM_SETFL_PRIV_MOD_PMCS; + if (ctx->state == PFM_CTX_MASKED) + return 1; + pfm_stop_active(task, ctx, ctx->active_set); if (arch_info->ctxswout_thread) diff --git a/arch/powerpc/perfmon/perfmon_power4.c b/arch/powerpc/perfmon/perfmon_power4.c index 6ea6dd5..c98a919 100644 --- a/arch/powerpc/perfmon/perfmon_power4.c +++ b/arch/powerpc/perfmon/perfmon_power4.c @@ -251,6 +251,16 @@ static void pfm_power4_irq_handler(struct pt_regs *regs, mtspr(SPRN_MMCR0, mmcr0); } +static void pfm_power4_resend_irq(struct pfm_context *ctx) +{ + /* + * Assert the PMAO bit to cause a PMU interrupt. Make sure we + * trigger the edge detection circuitry for PMAO + */ + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMAO); + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_PMAO); +} + struct pfm_arch_pmu_info pfm_power4_pmu_info = { .pmu_style = PFM_POWERPC_PMU_POWER4, .write_pmc = pfm_power4_write_pmc, @@ -260,6 +270,7 @@ struct pfm_arch_pmu_info pfm_power4_pmu_info = { .get_ovfl_pmds = pfm_power4_get_ovfl_pmds, .enable_counters = pfm_power4_enable_counters, .disable_counters = pfm_power4_disable_counters, + .resend_irq = pfm_power4_resend_irq }; /* diff --git a/arch/powerpc/perfmon/perfmon_power5.c b/arch/powerpc/perfmon/perfmon_power5.c index c6e050a..13346bf 100644 --- a/arch/powerpc/perfmon/perfmon_power5.c +++ b/arch/powerpc/perfmon/perfmon_power5.c @@ -283,6 +283,16 @@ static void pfm_power5_irq_handler(struct pt_regs *regs, mtspr(SPRN_MMCR0, mmcr0); } +static void pfm_power5_resend_irq(struct pfm_context *ctx) +{ + /* + * Assert the PMAO bit to cause a PMU interrupt. Make sure we + * trigger the edge detection circuitry for PMAO + */ + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMAO); + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_PMAO); +} + struct pfm_arch_pmu_info pfm_power5_pmu_info = { .pmu_style = PFM_POWERPC_PMU_POWER5, .write_pmc = pfm_power5_write_pmc, @@ -292,6 +302,7 @@ struct pfm_arch_pmu_info pfm_power5_pmu_info = { .get_ovfl_pmds = pfm_power5_get_ovfl_pmds, .enable_counters = pfm_power5_enable_counters, .disable_counters = pfm_power5_disable_counters, + .resend_irq = pfm_power5_resend_irq }; /* diff --git a/arch/powerpc/perfmon/perfmon_power6.c b/arch/powerpc/perfmon/perfmon_power6.c index d2070cb..ead3a66 100644 --- a/arch/powerpc/perfmon/perfmon_power6.c +++ b/arch/powerpc/perfmon/perfmon_power6.c @@ -441,6 +441,16 @@ static void pfm_power6_irq_handler(struct pt_regs *regs, mtspr(SPRN_MMCR0, mmcr0); } +static void pfm_power6_resend_irq(struct pfm_context *ctx) +{ + /* + * Assert the PMAO bit to cause a PMU interrupt. Make sure we + * trigger the edge detection circuitry for PMAO + */ + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMAO); + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_PMAO); +} + struct pfm_arch_pmu_info pfm_power6_pmu_info = { .pmu_style = PFM_POWERPC_PMU_POWER6, .write_pmc = pfm_power6_write_pmc, @@ -450,6 +460,7 @@ struct pfm_arch_pmu_info pfm_power6_pmu_info = { .get_ovfl_pmds = pfm_power6_get_ovfl_pmds, .enable_counters = pfm_power6_enable_counters, .disable_counters = pfm_power6_disable_counters, + .resend_irq = pfm_power6_resend_irq }; /* diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h index 7b56444..4fa87fc 100644 diff --git a/include/asm-powerpc/perfmon_kern.h b/include/asm-powerpc/perfmon_kern.h index b3c7d3e..9b0533b 100644 --- a/include/asm-powerpc/perfmon_kern.h +++ b/include/asm-powerpc/perfmon_kern.h @@ -128,6 +79,7 @@ struct pfm_arch_pmu_info { int (*acquire_pmu)(void); void (*release_pmu)(void); void *platform_info; + void (*resend_irq)(struct pfm_context *ctx); }; #ifdef CONFIG_PPC32 @@ -139,7 +91,12 @@ struct pfm_arch_pmu_info { #endif static inline void pfm_arch_resend_irq(struct pfm_context *ctx) -{} +{ + struct pfm_arch_pmu_info *arch_info; + + arch_info = pfm_pmu_info(); + arch_info->resend_irq(ctx); +} static inline void pfm_arch_serialize(void) {}
------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________ perfmon2-devel mailing list perfmon2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/perfmon2-devel