Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/cortex Optimize hardware priority updates.
details: https://anonhg.NetBSD.org/src/rev/de253b6c639d
branches: trunk
changeset: 951938:de253b6c639d
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sun Feb 07 21:24:50 2021 +0000
description:
Optimize hardware priority updates.
In gicv3_set_priority, read the current priority mask and only update it
if we are lowering the priority. The hardware priority filter is raised
only after taking an interrupt. This makes splfoo/splx without an interrupt
in between considerably cheaper as PMR writes are relatively expensive
compared to reads.
While here, avoid an extra daif read when dispatching interrupts by using
ENABLE_INTERRUPT() / DISABLE_INTERRUPT() instead of cpsie() / cpsid() macros.
diffstat:
sys/arch/arm/cortex/gicv3.c | 26 ++++++++++++++++++--------
1 files changed, 18 insertions(+), 8 deletions(-)
diffs (87 lines):
diff -r d9ebecf860f9 -r de253b6c639d sys/arch/arm/cortex/gicv3.c
--- a/sys/arch/arm/cortex/gicv3.c Sun Feb 07 21:18:37 2021 +0000
+++ b/sys/arch/arm/cortex/gicv3.c Sun Feb 07 21:24:50 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gicv3.c,v 1.39 2021/01/16 21:05:15 jmcneill Exp $ */
+/* $NetBSD: gicv3.c,v 1.40 2021/02/07 21:24:50 jmcneill Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -31,7 +31,7 @@
#define _INTR_PRIVATE
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.39 2021/01/16 21:05:15 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.40 2021/02/07 21:24:50 jmcneill Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -220,8 +220,13 @@
gicv3_set_priority(struct pic_softc *pic, int ipl)
{
struct gicv3_softc * const sc = PICTOSOFTC(pic);
+ const uint8_t curpmr = icc_pmr_read();
+ const uint8_t newpmr = IPL_TO_PMR(sc, ipl);
- icc_pmr_write(IPL_TO_PMR(sc, ipl));
+ if (newpmr > curpmr) {
+ /* Lowering priority mask */
+ icc_pmr_write(newpmr);
+ }
}
static void
@@ -407,7 +412,7 @@
;
/* Set initial priority mask */
- gicv3_set_priority(pic, IPL_HIGH);
+ icc_pmr_write(IPL_TO_PMR(sc, IPL_HIGH));
/* Set the binary point field to the minimum value */
icc_bpr1_write(0);
@@ -424,7 +429,7 @@
gicv3_redist_enable(sc, ci);
/* Allow IRQ exceptions */
- cpsie(I32_bit);
+ ENABLE_INTERRUPT();
}
#ifdef MULTIPROCESSOR
@@ -722,9 +727,14 @@
struct gicv3_softc * const sc = gicv3_softc;
struct pic_softc *pic;
const int oldipl = ci->ci_cpl;
+ const uint8_t pmr = IPL_TO_PMR(sc, oldipl);
ci->ci_data.cpu_nintr++;
+ if (icc_pmr_read() != pmr) {
+ icc_pmr_write(pmr);
+ }
+
for (;;) {
const uint32_t iar = icc_iar1_read();
dsb(sy);
@@ -745,7 +755,7 @@
if (__predict_false(ipl < ci->ci_cpl)) {
pic_do_pending_ints(I32_bit, ipl, frame);
} else if (ci->ci_cpl != ipl) {
- gicv3_set_priority(pic, ipl);
+ icc_pmr_write(IPL_TO_PMR(sc, ipl));
ci->ci_cpl = ipl;
}
@@ -756,9 +766,9 @@
const int64_t nintr = ci->ci_data.cpu_nintr;
- cpsie(I32_bit);
+ ENABLE_INTERRUPT();
pic_dispatch(is, frame);
- cpsid(I32_bit);
+ DISABLE_INTERRUPT();
if (nintr != ci->ci_data.cpu_nintr)
ci->ci_intr_preempt.ev_count++;
Home |
Main Index |
Thread Index |
Old Index