From: cheloha Date: Thu, 20 Apr 2023 00:24:11 +0000 (+0000) Subject: clockintr_cpu_init: mask CQ_INTRCLOCK while advancing schedule X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=5d42376813f3034d070cb21f9052029e8fa372b0;p=openbsd clockintr_cpu_init: mask CQ_INTRCLOCK while advancing schedule Allowing the intrclock to fire in the midst of clockintr_cpu_init() would complicate the function a lot. However, in a future patch we will need to enable intrclock operations in clockintr_advance(), clockintr_cancel(), and clockintr_schedule(). We can avoid this conflict by masking CQ_INTRCLOCK while we're updating the internal clockintrs in clockintr_cpu_init(). When we no longer need clockintr_cpu_init(), this workaround will disappear. --- diff --git a/sys/kern/kern_clockintr.c b/sys/kern/kern_clockintr.c index c163df71ab0..94ac0a7fd65 100644 --- a/sys/kern/kern_clockintr.c +++ b/sys/kern/kern_clockintr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_clockintr.c,v 1.11 2023/04/19 14:30:35 cheloha Exp $ */ +/* $OpenBSD: kern_clockintr.c,v 1.12 2023/04/20 00:24:11 cheloha Exp $ */ /* * Copyright (c) 2003 Dale Rahn * Copyright (c) 2020 Mark Kettenis @@ -110,6 +110,7 @@ clockintr_cpu_init(const struct intrclock *ic) uint64_t multiplier = 0, offset; struct cpu_info *ci = curcpu(); struct clockintr_queue *cq = &ci->ci_queue; + int reset_cq_intrclock = 0; KASSERT(ISSET(clockintr_flags, CL_INIT)); @@ -141,6 +142,16 @@ clockintr_cpu_init(const struct intrclock *ic) } } + /* + * Mask CQ_INTRCLOCK while we're advancing the internal clock + * interrupts. We don't want the intrclock to fire until this + * thread reaches clockintr_trigger(). + */ + if (ISSET(cq->cq_flags, CQ_INTRCLOCK)) { + CLR(cq->cq_flags, CQ_INTRCLOCK); + reset_cq_intrclock = 1; + } + /* * Until we understand scheduler lock contention better, stagger * the hardclock and statclock so they don't all happen at once. @@ -176,6 +187,9 @@ clockintr_cpu_init(const struct intrclock *ic) clockintr_advance(cq->cq_schedclock, schedclock_period); } + if (reset_cq_intrclock) + SET(cq->cq_flags, CQ_INTRCLOCK); + SET(cq->cq_flags, CQ_INIT); }