-/* $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>
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
-/* $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>
int nstats;
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.
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
-/* $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>
{
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);