diff options
author | Scott Soule Cheloha <cheloha@cvs.openbsd.org> | 2022-08-09 04:40:09 +0000 |
---|---|---|
committer | Scott Soule Cheloha <cheloha@cvs.openbsd.org> | 2022-08-09 04:40:09 +0000 |
commit | eb271bbf049b099f905d8e2191de9e49b6bc4f70 (patch) | |
tree | 50d2e6b0895c3b627804fdcd13d1ce95bd968c84 /sys/arch | |
parent | f35e53196e820d63b533298688c38c3e1f1f4b65 (diff) |
powerpc64: trigger deferred DEC interrupts from splx(9)
In order to move to a machine-independent clock interrupt subsystem,
the powerpc64 clock interrupt code needs to work without knowing
anything about the clock interrupt schedule.
The easiest way to do this is, if the DEC fires while the CPU's IPL is
at or above IPL_CLOCK, to postpone clock interrupt work until the
clock interrupt is logically unmasked from splx(9).
Because we no longer defer work until the next tick, we don't need to
keep track of pending statclock ticks in the cpu_info struct.
With input from kettenis@.
Graciously compiled and tested by gkoehler@ and kettenis@.
Link: https://marc.info/?l=openbsd-tech&m=165862522102767&w=2
ok kettenis@ gkoehler@.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/powerpc64/include/cpu.h | 4 | ||||
-rw-r--r-- | sys/arch/powerpc64/powerpc64/clock.c | 52 | ||||
-rw-r--r-- | sys/arch/powerpc64/powerpc64/intr.c | 7 |
3 files changed, 36 insertions, 27 deletions
diff --git a/sys/arch/powerpc64/include/cpu.h b/sys/arch/powerpc64/include/cpu.h index 7825e62dfbc..7df5a2ba921 100644 --- a/sys/arch/powerpc64/include/cpu.h +++ b/sys/arch/powerpc64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.31 2021/07/06 09:34:07 kettenis Exp $ */ +/* $OpenBSD: cpu.h,v 1.32 2022/08/09 04:40:08 cheloha Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -74,9 +74,9 @@ struct cpu_info { uint64_t ci_lasttb; uint64_t ci_nexttimerevent; uint64_t ci_nextstatevent; - int ci_statspending; volatile int ci_cpl; + volatile int ci_dec_deferred; uint32_t ci_ipending; uint32_t ci_idepth; #ifdef DIAGNOSTIC diff --git a/sys/arch/powerpc64/powerpc64/clock.c b/sys/arch/powerpc64/powerpc64/clock.c index 204ce0fcac2..31d1769e109 100644 --- a/sys/arch/powerpc64/powerpc64/clock.c +++ b/sys/arch/powerpc64/powerpc64/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.3 2021/02/23 04:44:31 cheloha Exp $ */ +/* $OpenBSD: clock.c,v 1.4 2022/08/09 04:40:08 cheloha Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -98,6 +98,17 @@ decr_intr(struct trapframe *frame) int s; /* + * If the clock interrupt is masked, postpone all work until + * it is unmasked in splx(9). + */ + if (ci->ci_cpl >= IPL_CLOCK) { + ci->ci_dec_deferred = 1; + mtdec(UINT32_MAX >> 1); /* clear DEC exception */ + return; + } + ci->ci_dec_deferred = 0; + + /* * Based on the actual time delay since the last decrementer reload, * we arrange for earlier interrupt next time. */ @@ -130,30 +141,23 @@ decr_intr(struct trapframe *frame) mtdec(nextevent - tb); mtdec(nextevent - mftb()); - if (ci->ci_cpl >= IPL_CLOCK) { - ci->ci_statspending += nstats; - } else { - nstats += ci->ci_statspending; - ci->ci_statspending = 0; - - s = splclock(); - intr_enable(); - - /* - * Do standard timer interrupt stuff. - */ - while (ci->ci_lasttb < prevtb) { - ci->ci_lasttb += tick_increment; - clock_count.ec_count++; - hardclock((struct clockframe *)frame); - } - - while (nstats-- > 0) - statclock((struct clockframe *)frame); - - intr_disable(); - splx(s); + s = splclock(); + intr_enable(); + + /* + * Do standard timer interrupt stuff. + */ + while (ci->ci_lasttb < prevtb) { + ci->ci_lasttb += tick_increment; + clock_count.ec_count++; + hardclock((struct clockframe *)frame); } + + while (nstats-- > 0) + statclock((struct clockframe *)frame); + + intr_disable(); + splx(s); } void diff --git a/sys/arch/powerpc64/powerpc64/intr.c b/sys/arch/powerpc64/powerpc64/intr.c index ebcf4ef7ba8..022db1b6446 100644 --- a/sys/arch/powerpc64/powerpc64/intr.c +++ b/sys/arch/powerpc64/powerpc64/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.10 2022/07/27 20:26:17 kettenis Exp $ */ +/* $OpenBSD: intr.c,v 1.11 2022/08/09 04:40:08 cheloha Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -139,6 +139,11 @@ splx(int new) { struct cpu_info *ci = curcpu(); + if (ci->ci_dec_deferred && new < IPL_CLOCK) { + mtdec(0); + mtdec(UINT32_MAX); /* raise DEC exception */ + } + if (ci->ci_ipending & intr_smask[new]) intr_do_pending(new); |