From 8183e2b38480672a1f61d416812ac078ce94b67b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jan 2010 15:37:04 -0800 Subject: sparc64: Fix NMI programming when perf events are active. If perf events are active, we should not reset the %pcr to PCR_PIC_PRIV. That perf events code does the management. Signed-off-by: David S. Miller --- arch/sparc/kernel/nmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c index f30f4a1ead23..d242a7340541 100644 --- a/arch/sparc/kernel/nmi.c +++ b/arch/sparc/kernel/nmi.c @@ -96,7 +96,6 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) int cpu = smp_processor_id(); clear_softint(1 << irq); - pcr_ops->write(PCR_PIC_PRIV); local_cpu_data().__nmi_count++; @@ -105,6 +104,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) if (notify_die(DIE_NMI, "nmi", regs, 0, pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) touched = 1; + else + pcr_ops->write(PCR_PIC_PRIV); sum = kstat_irqs_cpu(0, cpu); if (__get_cpu_var(nmi_touch)) { -- cgit v1.2.3 From e04ed38d4e0cd32141f723560efcc8252b0241e2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jan 2010 23:16:03 -0800 Subject: sparc64: Fix Niagara2 perf event handling. For chips like Niagara2 that have true overflow indications in the %pcr (which we don't actually need and don't use) the interrupt signal persists until the overflow bits are cleared by an explicit %pcr write. Signed-off-by: David S. Miller --- arch/sparc/kernel/perf_event.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index fa5936e1c3b9..198fb4e79ba2 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -986,6 +986,17 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self, data.addr = 0; cpuc = &__get_cpu_var(cpu_hw_events); + + /* If the PMU has the TOE IRQ enable bits, we need to do a + * dummy write to the %pcr to clear the overflow bits and thus + * the interrupt. + * + * Do this before we peek at the counters to determine + * overflow so we don't lose any events. + */ + if (sparc_pmu->irq_bit) + pcr_ops->write(cpuc->pcr); + for (idx = 0; idx < MAX_HWEVENTS; idx++) { struct perf_event *event = cpuc->events[idx]; struct hw_perf_event *hwc; -- cgit v1.2.3