Index: sys/kern/kern_clocksource.c =================================================================== --- sys/kern/kern_clocksource.c +++ sys/kern/kern_clocksource.c @@ -65,7 +65,8 @@ static void configtimer(int start); static int round_freq(struct eventtimer *et, int freq); -static sbintime_t getnextcpuevent(int idle); +struct pcpu_state; +static sbintime_t getnextcpuevent(struct pcpu_state *state, int idle); static sbintime_t getnextevent(void); static int handleevents(sbintime_t now, int fake); @@ -212,9 +213,8 @@ state->nextcall = state->nextcallopt = SBT_MAX; callout_process(now); } - - t = getnextcpuevent(0); ET_HW_LOCK(state); + t = getnextcpuevent(state, 0); if (!busy) { state->idle = 0; state->nextevent = t; @@ -229,13 +229,11 @@ * Schedule binuptime of the next event on current CPU. */ static sbintime_t -getnextcpuevent(int idle) +getnextcpuevent(struct pcpu_state *state, int idle) { sbintime_t event; - struct pcpu_state *state; u_int hardfreq; - state = DPCPU_PTR(timerstate); /* Handle hardclock() events, skipping some if CPU is idle. */ event = state->nexthard; if (idle) { @@ -686,8 +684,8 @@ struct thread *td; state = DPCPU_PTR(timerstate); - now = sbinuptime(); ET_HW_LOCK(state); + now = sbinuptime(); state->now = now; hardclock_sync(curcpu); spinlock_enter(); @@ -772,14 +770,14 @@ ) return (-1); state = DPCPU_PTR(timerstate); + ET_HW_LOCK(state); if (periodic) now = state->now; else now = sbinuptime(); CTR3(KTR_SPARE2, "idle at %d: now %d.%08x", curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff)); - t = getnextcpuevent(1); - ET_HW_LOCK(state); + t = getnextcpuevent(state, 1); state->idle = 1; state->nextevent = t; if (!periodic) @@ -799,15 +797,15 @@ struct thread *td; state = DPCPU_PTR(timerstate); - if (state->idle == 0 || busy) + if (atomic_load_int(&state->idle) == 0 || busy) return; + spinlock_enter(); if (periodic) now = state->now; else now = sbinuptime(); CTR3(KTR_SPARE2, "active at %d: now %d.%08x", curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff)); - spinlock_enter(); td = curthread; td->td_intr_nesting_level++; handleevents(now, 1);