Commit 4d431290 authored by Vineet Gupta's avatar Vineet Gupta

ARCv2: perf: tweak overflow interrupt

Current perf ISR loops thru all 32 counters, checking for each if it
caused the interrupt. Instead only loop thru counters which actually
interrupted (typically 1).
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarVineet Gupta <vgupta@synopsys.com>
parent ff64d695
...@@ -377,21 +377,22 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev) ...@@ -377,21 +377,22 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev)
struct perf_sample_data data; struct perf_sample_data data;
struct arc_pmu_cpu *pmu_cpu = this_cpu_ptr(&arc_pmu_cpu); struct arc_pmu_cpu *pmu_cpu = this_cpu_ptr(&arc_pmu_cpu);
struct pt_regs *regs; struct pt_regs *regs;
int active_ints; unsigned int active_ints;
int idx; int idx;
arc_pmu_disable(&arc_pmu->pmu); arc_pmu_disable(&arc_pmu->pmu);
active_ints = read_aux_reg(ARC_REG_PCT_INT_ACT); active_ints = read_aux_reg(ARC_REG_PCT_INT_ACT);
if (!active_ints)
goto done;
regs = get_irq_regs(); regs = get_irq_regs();
for (idx = 0; idx < arc_pmu->n_counters; idx++) { do {
struct perf_event *event = pmu_cpu->act_counter[idx]; struct perf_event *event;
struct hw_perf_event *hwc; struct hw_perf_event *hwc;
if (!(active_ints & (1 << idx))) idx = __ffs(active_ints);
continue;
/* Reset interrupt flag by writing of 1 */ /* Reset interrupt flag by writing of 1 */
write_aux_reg(ARC_REG_PCT_INT_ACT, 1 << idx); write_aux_reg(ARC_REG_PCT_INT_ACT, 1 << idx);
...@@ -404,19 +405,22 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev) ...@@ -404,19 +405,22 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev)
write_aux_reg(ARC_REG_PCT_INT_CTRL, write_aux_reg(ARC_REG_PCT_INT_CTRL,
read_aux_reg(ARC_REG_PCT_INT_CTRL) | (1 << idx)); read_aux_reg(ARC_REG_PCT_INT_CTRL) | (1 << idx));
event = pmu_cpu->act_counter[idx];
hwc = &event->hw; hwc = &event->hw;
WARN_ON_ONCE(hwc->idx != idx); WARN_ON_ONCE(hwc->idx != idx);
arc_perf_event_update(event, &event->hw, event->hw.idx); arc_perf_event_update(event, &event->hw, event->hw.idx);
perf_sample_data_init(&data, 0, hwc->last_period); perf_sample_data_init(&data, 0, hwc->last_period);
if (!arc_pmu_event_set_period(event)) if (arc_pmu_event_set_period(event)) {
continue; if (perf_event_overflow(event, &data, regs))
arc_pmu_stop(event, 0);
}
if (perf_event_overflow(event, &data, regs)) active_ints &= ~(1U << idx);
arc_pmu_stop(event, 0); } while (active_ints);
}
done:
arc_pmu_enable(&arc_pmu->pmu); arc_pmu_enable(&arc_pmu->pmu);
return IRQ_HANDLED; return IRQ_HANDLED;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment