Sat Jun 27 01:26:32 2020 UTC ()
Stop allocating struct cpu_info in BSS; No need to db_read_bytes()
against cpu_info, just ci_data.cpu_callout is enough.

Save 1408 bytes of BSS for, e.g., aarch64.


(rin)
diff -r1.65 -r1.66 src/sys/kern/kern_timeout.c

cvs diff -r1.65 -r1.66 src/sys/kern/kern_timeout.c (switch to unified diff)

--- src/sys/kern/kern_timeout.c 2020/06/02 02:04:35 1.65
+++ src/sys/kern/kern_timeout.c 2020/06/27 01:26:32 1.66
@@ -1,871 +1,872 @@ @@ -1,871 +1,872 @@
1/* $NetBSD: kern_timeout.c,v 1.65 2020/06/02 02:04:35 rin Exp $ */ 1/* $NetBSD: kern_timeout.c,v 1.66 2020/06/27 01:26:32 rin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003, 2006, 2007, 2008, 2009, 2019 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003, 2006, 2007, 2008, 2009, 2019 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe, and by Andrew Doran. 8 * by Jason R. Thorpe, and by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 2001 Thomas Nordin <nordin@openbsd.org> 33 * Copyright (c) 2001 Thomas Nordin <nordin@openbsd.org>
34 * Copyright (c) 2000-2001 Artur Grabowski <art@openbsd.org> 34 * Copyright (c) 2000-2001 Artur Grabowski <art@openbsd.org>
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions 38 * modification, are permitted provided that the following conditions
39 * are met: 39 * are met:
40 * 40 *
41 * 1. Redistributions of source code must retain the above copyright 41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer. 42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright 43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the 44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution. 45 * documentation and/or other materials provided with the distribution.
46 * 3. The name of the author may not be used to endorse or promote products 46 * 3. The name of the author may not be used to endorse or promote products
47 * derived from this software without specific prior written permission. 47 * derived from this software without specific prior written permission.
48 * 48 *
49 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 49 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
50 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 50 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
51 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 51 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
52 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 52 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
53 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 53 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
54 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 54 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
55 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 55 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
56 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 56 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
57 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 57 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
58 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 58 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 */ 59 */
60 60
61#include <sys/cdefs.h> 61#include <sys/cdefs.h>
62__KERNEL_RCSID(0, "$NetBSD: kern_timeout.c,v 1.65 2020/06/02 02:04:35 rin Exp $"); 62__KERNEL_RCSID(0, "$NetBSD: kern_timeout.c,v 1.66 2020/06/27 01:26:32 rin Exp $");
63 63
64/* 64/*
65 * Timeouts are kept in a hierarchical timing wheel. The c_time is the 65 * Timeouts are kept in a hierarchical timing wheel. The c_time is the
66 * value of c_cpu->cc_ticks when the timeout should be called. There are 66 * value of c_cpu->cc_ticks when the timeout should be called. There are
67 * four levels with 256 buckets each. See 'Scheme 7' in "Hashed and 67 * four levels with 256 buckets each. See 'Scheme 7' in "Hashed and
68 * Hierarchical Timing Wheels: Efficient Data Structures for Implementing 68 * Hierarchical Timing Wheels: Efficient Data Structures for Implementing
69 * a Timer Facility" by George Varghese and Tony Lauck. 69 * a Timer Facility" by George Varghese and Tony Lauck.
70 * 70 *
71 * Some of the "math" in here is a bit tricky. We have to beware of 71 * Some of the "math" in here is a bit tricky. We have to beware of
72 * wrapping ints. 72 * wrapping ints.
73 * 73 *
74 * We use the fact that any element added to the queue must be added with 74 * We use the fact that any element added to the queue must be added with
75 * a positive time. That means that any element `to' on the queue cannot 75 * a positive time. That means that any element `to' on the queue cannot
76 * be scheduled to timeout further in time than INT_MAX, but c->c_time can 76 * be scheduled to timeout further in time than INT_MAX, but c->c_time can
77 * be positive or negative so comparing it with anything is dangerous.  77 * be positive or negative so comparing it with anything is dangerous.
78 * The only way we can use the c->c_time value in any predictable way is 78 * The only way we can use the c->c_time value in any predictable way is
79 * when we calculate how far in the future `to' will timeout - "c->c_time 79 * when we calculate how far in the future `to' will timeout - "c->c_time
80 * - c->c_cpu->cc_ticks". The result will always be positive for future 80 * - c->c_cpu->cc_ticks". The result will always be positive for future
81 * timeouts and 0 or negative for due timeouts. 81 * timeouts and 0 or negative for due timeouts.
82 */ 82 */
83 83
84#define _CALLOUT_PRIVATE 84#define _CALLOUT_PRIVATE
85 85
86#include <sys/param.h> 86#include <sys/param.h>
87#include <sys/systm.h> 87#include <sys/systm.h>
88#include <sys/kernel.h> 88#include <sys/kernel.h>
89#include <sys/callout.h> 89#include <sys/callout.h>
90#include <sys/lwp.h> 90#include <sys/lwp.h>
91#include <sys/mutex.h> 91#include <sys/mutex.h>
92#include <sys/proc.h> 92#include <sys/proc.h>
93#include <sys/sleepq.h> 93#include <sys/sleepq.h>
94#include <sys/syncobj.h> 94#include <sys/syncobj.h>
95#include <sys/evcnt.h> 95#include <sys/evcnt.h>
96#include <sys/intr.h> 96#include <sys/intr.h>
97#include <sys/cpu.h> 97#include <sys/cpu.h>
98#include <sys/kmem.h> 98#include <sys/kmem.h>
99 99
100#ifdef DDB 100#ifdef DDB
101#include <machine/db_machdep.h> 101#include <machine/db_machdep.h>
102#include <ddb/db_interface.h> 102#include <ddb/db_interface.h>
103#include <ddb/db_access.h> 103#include <ddb/db_access.h>
104#include <ddb/db_cpu.h> 104#include <ddb/db_cpu.h>
105#include <ddb/db_sym.h> 105#include <ddb/db_sym.h>
106#include <ddb/db_output.h> 106#include <ddb/db_output.h>
107#endif 107#endif
108 108
109#define BUCKETS 1024 109#define BUCKETS 1024
110#define WHEELSIZE 256 110#define WHEELSIZE 256
111#define WHEELMASK 255 111#define WHEELMASK 255
112#define WHEELBITS 8 112#define WHEELBITS 8
113 113
114#define MASKWHEEL(wheel, time) (((time) >> ((wheel)*WHEELBITS)) & WHEELMASK) 114#define MASKWHEEL(wheel, time) (((time) >> ((wheel)*WHEELBITS)) & WHEELMASK)
115 115
116#define BUCKET(cc, rel, abs) \ 116#define BUCKET(cc, rel, abs) \
117 (((rel) <= (1 << (2*WHEELBITS))) \ 117 (((rel) <= (1 << (2*WHEELBITS))) \
118 ? ((rel) <= (1 << WHEELBITS)) \ 118 ? ((rel) <= (1 << WHEELBITS)) \
119 ? &(cc)->cc_wheel[MASKWHEEL(0, (abs))] \ 119 ? &(cc)->cc_wheel[MASKWHEEL(0, (abs))] \
120 : &(cc)->cc_wheel[MASKWHEEL(1, (abs)) + WHEELSIZE] \ 120 : &(cc)->cc_wheel[MASKWHEEL(1, (abs)) + WHEELSIZE] \
121 : ((rel) <= (1 << (3*WHEELBITS))) \ 121 : ((rel) <= (1 << (3*WHEELBITS))) \
122 ? &(cc)->cc_wheel[MASKWHEEL(2, (abs)) + 2*WHEELSIZE] \ 122 ? &(cc)->cc_wheel[MASKWHEEL(2, (abs)) + 2*WHEELSIZE] \
123 : &(cc)->cc_wheel[MASKWHEEL(3, (abs)) + 3*WHEELSIZE]) 123 : &(cc)->cc_wheel[MASKWHEEL(3, (abs)) + 3*WHEELSIZE])
124 124
125#define MOVEBUCKET(cc, wheel, time) \ 125#define MOVEBUCKET(cc, wheel, time) \
126 CIRCQ_APPEND(&(cc)->cc_todo, \ 126 CIRCQ_APPEND(&(cc)->cc_todo, \
127 &(cc)->cc_wheel[MASKWHEEL((wheel), (time)) + (wheel)*WHEELSIZE]) 127 &(cc)->cc_wheel[MASKWHEEL((wheel), (time)) + (wheel)*WHEELSIZE])
128 128
129/* 129/*
130 * Circular queue definitions. 130 * Circular queue definitions.
131 */ 131 */
132 132
133#define CIRCQ_INIT(list) \ 133#define CIRCQ_INIT(list) \
134do { \ 134do { \
135 (list)->cq_next_l = (list); \ 135 (list)->cq_next_l = (list); \
136 (list)->cq_prev_l = (list); \ 136 (list)->cq_prev_l = (list); \
137} while (/*CONSTCOND*/0) 137} while (/*CONSTCOND*/0)
138 138
139#define CIRCQ_INSERT(elem, list) \ 139#define CIRCQ_INSERT(elem, list) \
140do { \ 140do { \
141 (elem)->cq_prev_e = (list)->cq_prev_e; \ 141 (elem)->cq_prev_e = (list)->cq_prev_e; \
142 (elem)->cq_next_l = (list); \ 142 (elem)->cq_next_l = (list); \
143 (list)->cq_prev_l->cq_next_l = (elem); \ 143 (list)->cq_prev_l->cq_next_l = (elem); \
144 (list)->cq_prev_l = (elem); \ 144 (list)->cq_prev_l = (elem); \
145} while (/*CONSTCOND*/0) 145} while (/*CONSTCOND*/0)
146 146
147#define CIRCQ_APPEND(fst, snd) \ 147#define CIRCQ_APPEND(fst, snd) \
148do { \ 148do { \
149 if (!CIRCQ_EMPTY(snd)) { \ 149 if (!CIRCQ_EMPTY(snd)) { \
150 (fst)->cq_prev_l->cq_next_l = (snd)->cq_next_l; \ 150 (fst)->cq_prev_l->cq_next_l = (snd)->cq_next_l; \
151 (snd)->cq_next_l->cq_prev_l = (fst)->cq_prev_l; \ 151 (snd)->cq_next_l->cq_prev_l = (fst)->cq_prev_l; \
152 (snd)->cq_prev_l->cq_next_l = (fst); \ 152 (snd)->cq_prev_l->cq_next_l = (fst); \
153 (fst)->cq_prev_l = (snd)->cq_prev_l; \ 153 (fst)->cq_prev_l = (snd)->cq_prev_l; \
154 CIRCQ_INIT(snd); \ 154 CIRCQ_INIT(snd); \
155 } \ 155 } \
156} while (/*CONSTCOND*/0) 156} while (/*CONSTCOND*/0)
157 157
158#define CIRCQ_REMOVE(elem) \ 158#define CIRCQ_REMOVE(elem) \
159do { \ 159do { \
160 (elem)->cq_next_l->cq_prev_e = (elem)->cq_prev_e; \ 160 (elem)->cq_next_l->cq_prev_e = (elem)->cq_prev_e; \
161 (elem)->cq_prev_l->cq_next_e = (elem)->cq_next_e; \ 161 (elem)->cq_prev_l->cq_next_e = (elem)->cq_next_e; \
162} while (/*CONSTCOND*/0) 162} while (/*CONSTCOND*/0)
163 163
164#define CIRCQ_FIRST(list) ((list)->cq_next_e) 164#define CIRCQ_FIRST(list) ((list)->cq_next_e)
165#define CIRCQ_NEXT(elem) ((elem)->cq_next_e) 165#define CIRCQ_NEXT(elem) ((elem)->cq_next_e)
166#define CIRCQ_LAST(elem,list) ((elem)->cq_next_l == (list)) 166#define CIRCQ_LAST(elem,list) ((elem)->cq_next_l == (list))
167#define CIRCQ_EMPTY(list) ((list)->cq_next_l == (list)) 167#define CIRCQ_EMPTY(list) ((list)->cq_next_l == (list))
168 168
169struct callout_cpu { 169struct callout_cpu {
170 kmutex_t *cc_lock; 170 kmutex_t *cc_lock;
171 sleepq_t cc_sleepq; 171 sleepq_t cc_sleepq;
172 u_int cc_nwait; 172 u_int cc_nwait;
173 u_int cc_ticks; 173 u_int cc_ticks;
174 lwp_t *cc_lwp; 174 lwp_t *cc_lwp;
175 callout_impl_t *cc_active; 175 callout_impl_t *cc_active;
176 callout_impl_t *cc_cancel; 176 callout_impl_t *cc_cancel;
177 struct evcnt cc_ev_late; 177 struct evcnt cc_ev_late;
178 struct evcnt cc_ev_block; 178 struct evcnt cc_ev_block;
179 struct callout_circq cc_todo; /* Worklist */ 179 struct callout_circq cc_todo; /* Worklist */
180 struct callout_circq cc_wheel[BUCKETS]; /* Queues of timeouts */ 180 struct callout_circq cc_wheel[BUCKETS]; /* Queues of timeouts */
181 char cc_name1[12]; 181 char cc_name1[12];
182 char cc_name2[12]; 182 char cc_name2[12];
183}; 183};
184 184
185#ifdef DDB 185#ifdef DDB
186static struct callout_cpu ccb; 186static struct callout_cpu ccb;
187static struct cpu_info cib; 
188#endif 187#endif
189 188
190#ifndef CRASH /* _KERNEL */ 189#ifndef CRASH /* _KERNEL */
191static void callout_softclock(void *); 190static void callout_softclock(void *);
192static void callout_wait(callout_impl_t *, void *, kmutex_t *); 191static void callout_wait(callout_impl_t *, void *, kmutex_t *);
193 192
194static struct callout_cpu callout_cpu0 __cacheline_aligned; 193static struct callout_cpu callout_cpu0 __cacheline_aligned;
195static void *callout_sih __read_mostly; 194static void *callout_sih __read_mostly;
196 195
197static inline kmutex_t * 196static inline kmutex_t *
198callout_lock(callout_impl_t *c) 197callout_lock(callout_impl_t *c)
199{ 198{
200 struct callout_cpu *cc; 199 struct callout_cpu *cc;
201 kmutex_t *lock; 200 kmutex_t *lock;
202 201
203 for (;;) { 202 for (;;) {
204 cc = c->c_cpu; 203 cc = c->c_cpu;
205 lock = cc->cc_lock; 204 lock = cc->cc_lock;
206 mutex_spin_enter(lock); 205 mutex_spin_enter(lock);
207 if (__predict_true(cc == c->c_cpu)) 206 if (__predict_true(cc == c->c_cpu))
208 return lock; 207 return lock;
209 mutex_spin_exit(lock); 208 mutex_spin_exit(lock);
210 } 209 }
211} 210}
212 211
213/* 212/*
214 * callout_startup: 213 * callout_startup:
215 * 214 *
216 * Initialize the callout facility, called at system startup time. 215 * Initialize the callout facility, called at system startup time.
217 * Do just enough to allow callouts to be safely registered. 216 * Do just enough to allow callouts to be safely registered.
218 */ 217 */
219void 218void
220callout_startup(void) 219callout_startup(void)
221{ 220{
222 struct callout_cpu *cc; 221 struct callout_cpu *cc;
223 int b; 222 int b;
224 223
225 KASSERT(curcpu()->ci_data.cpu_callout == NULL); 224 KASSERT(curcpu()->ci_data.cpu_callout == NULL);
226 225
227 cc = &callout_cpu0; 226 cc = &callout_cpu0;
228 cc->cc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SCHED); 227 cc->cc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SCHED);
229 CIRCQ_INIT(&cc->cc_todo); 228 CIRCQ_INIT(&cc->cc_todo);
230 for (b = 0; b < BUCKETS; b++) 229 for (b = 0; b < BUCKETS; b++)
231 CIRCQ_INIT(&cc->cc_wheel[b]); 230 CIRCQ_INIT(&cc->cc_wheel[b]);
232 curcpu()->ci_data.cpu_callout = cc; 231 curcpu()->ci_data.cpu_callout = cc;
233} 232}
234 233
235/* 234/*
236 * callout_init_cpu: 235 * callout_init_cpu:
237 * 236 *
238 * Per-CPU initialization. 237 * Per-CPU initialization.
239 */ 238 */
240CTASSERT(sizeof(callout_impl_t) <= sizeof(callout_t)); 239CTASSERT(sizeof(callout_impl_t) <= sizeof(callout_t));
241 240
242void 241void
243callout_init_cpu(struct cpu_info *ci) 242callout_init_cpu(struct cpu_info *ci)
244{ 243{
245 struct callout_cpu *cc; 244 struct callout_cpu *cc;
246 int b; 245 int b;
247 246
248 if ((cc = ci->ci_data.cpu_callout) == NULL) { 247 if ((cc = ci->ci_data.cpu_callout) == NULL) {
249 cc = kmem_zalloc(sizeof(*cc), KM_SLEEP); 248 cc = kmem_zalloc(sizeof(*cc), KM_SLEEP);
250 cc->cc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SCHED); 249 cc->cc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SCHED);
251 CIRCQ_INIT(&cc->cc_todo); 250 CIRCQ_INIT(&cc->cc_todo);
252 for (b = 0; b < BUCKETS; b++) 251 for (b = 0; b < BUCKETS; b++)
253 CIRCQ_INIT(&cc->cc_wheel[b]); 252 CIRCQ_INIT(&cc->cc_wheel[b]);
254 } else { 253 } else {
255 /* Boot CPU, one time only. */ 254 /* Boot CPU, one time only. */
256 callout_sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE, 255 callout_sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE,
257 callout_softclock, NULL); 256 callout_softclock, NULL);
258 if (callout_sih == NULL) 257 if (callout_sih == NULL)
259 panic("callout_init_cpu (2)"); 258 panic("callout_init_cpu (2)");
260 } 259 }
261 260
262 sleepq_init(&cc->cc_sleepq); 261 sleepq_init(&cc->cc_sleepq);
263 262
264 snprintf(cc->cc_name1, sizeof(cc->cc_name1), "late/%u", 263 snprintf(cc->cc_name1, sizeof(cc->cc_name1), "late/%u",
265 cpu_index(ci)); 264 cpu_index(ci));
266 evcnt_attach_dynamic(&cc->cc_ev_late, EVCNT_TYPE_MISC, 265 evcnt_attach_dynamic(&cc->cc_ev_late, EVCNT_TYPE_MISC,
267 NULL, "callout", cc->cc_name1); 266 NULL, "callout", cc->cc_name1);
268 267
269 snprintf(cc->cc_name2, sizeof(cc->cc_name2), "wait/%u", 268 snprintf(cc->cc_name2, sizeof(cc->cc_name2), "wait/%u",
270 cpu_index(ci)); 269 cpu_index(ci));
271 evcnt_attach_dynamic(&cc->cc_ev_block, EVCNT_TYPE_MISC, 270 evcnt_attach_dynamic(&cc->cc_ev_block, EVCNT_TYPE_MISC,
272 NULL, "callout", cc->cc_name2); 271 NULL, "callout", cc->cc_name2);
273 272
274 ci->ci_data.cpu_callout = cc; 273 ci->ci_data.cpu_callout = cc;
275} 274}
276 275
277/* 276/*
278 * callout_init: 277 * callout_init:
279 * 278 *
280 * Initialize a callout structure. This must be quick, so we fill 279 * Initialize a callout structure. This must be quick, so we fill
281 * only the minimum number of fields. 280 * only the minimum number of fields.
282 */ 281 */
283void 282void
284callout_init(callout_t *cs, u_int flags) 283callout_init(callout_t *cs, u_int flags)
285{ 284{
286 callout_impl_t *c = (callout_impl_t *)cs; 285 callout_impl_t *c = (callout_impl_t *)cs;
287 struct callout_cpu *cc; 286 struct callout_cpu *cc;
288 287
289 KASSERT((flags & ~CALLOUT_FLAGMASK) == 0); 288 KASSERT((flags & ~CALLOUT_FLAGMASK) == 0);
290 289
291 cc = curcpu()->ci_data.cpu_callout; 290 cc = curcpu()->ci_data.cpu_callout;
292 c->c_func = NULL; 291 c->c_func = NULL;
293 c->c_magic = CALLOUT_MAGIC; 292 c->c_magic = CALLOUT_MAGIC;
294 if (__predict_true((flags & CALLOUT_MPSAFE) != 0 && cc != NULL)) { 293 if (__predict_true((flags & CALLOUT_MPSAFE) != 0 && cc != NULL)) {
295 c->c_flags = flags; 294 c->c_flags = flags;
296 c->c_cpu = cc; 295 c->c_cpu = cc;
297 return; 296 return;
298 } 297 }
299 c->c_flags = flags | CALLOUT_BOUND; 298 c->c_flags = flags | CALLOUT_BOUND;
300 c->c_cpu = &callout_cpu0; 299 c->c_cpu = &callout_cpu0;
301} 300}
302 301
303/* 302/*
304 * callout_destroy: 303 * callout_destroy:
305 * 304 *
306 * Destroy a callout structure. The callout must be stopped. 305 * Destroy a callout structure. The callout must be stopped.
307 */ 306 */
308void 307void
309callout_destroy(callout_t *cs) 308callout_destroy(callout_t *cs)
310{ 309{
311 callout_impl_t *c = (callout_impl_t *)cs; 310 callout_impl_t *c = (callout_impl_t *)cs;
312 311
313 KASSERTMSG(c->c_magic == CALLOUT_MAGIC, 312 KASSERTMSG(c->c_magic == CALLOUT_MAGIC,
314 "callout %p: c_magic (%#x) != CALLOUT_MAGIC (%#x)", 313 "callout %p: c_magic (%#x) != CALLOUT_MAGIC (%#x)",
315 c, c->c_magic, CALLOUT_MAGIC); 314 c, c->c_magic, CALLOUT_MAGIC);
316 /* 315 /*
317 * It's not necessary to lock in order to see the correct value 316 * It's not necessary to lock in order to see the correct value
318 * of c->c_flags. If the callout could potentially have been 317 * of c->c_flags. If the callout could potentially have been
319 * running, the current thread should have stopped it. 318 * running, the current thread should have stopped it.
320 */ 319 */
321 KASSERTMSG((c->c_flags & CALLOUT_PENDING) == 0, 320 KASSERTMSG((c->c_flags & CALLOUT_PENDING) == 0,
322 "pending callout %p: c_func (%p) c_flags (%#x) destroyed from %p", 321 "pending callout %p: c_func (%p) c_flags (%#x) destroyed from %p",
323 c, c->c_func, c->c_flags, __builtin_return_address(0)); 322 c, c->c_func, c->c_flags, __builtin_return_address(0));
324 KASSERTMSG(c->c_cpu->cc_lwp == curlwp || c->c_cpu->cc_active != c, 323 KASSERTMSG(c->c_cpu->cc_lwp == curlwp || c->c_cpu->cc_active != c,
325 "running callout %p: c_func (%p) c_flags (%#x) destroyed from %p", 324 "running callout %p: c_func (%p) c_flags (%#x) destroyed from %p",
326 c, c->c_func, c->c_flags, __builtin_return_address(0)); 325 c, c->c_func, c->c_flags, __builtin_return_address(0));
327 c->c_magic = 0; 326 c->c_magic = 0;
328} 327}
329 328
330/* 329/*
331 * callout_schedule_locked: 330 * callout_schedule_locked:
332 * 331 *
333 * Schedule a callout to run. The function and argument must 332 * Schedule a callout to run. The function and argument must
334 * already be set in the callout structure. Must be called with 333 * already be set in the callout structure. Must be called with
335 * callout_lock. 334 * callout_lock.
336 */ 335 */
337static void 336static void
338callout_schedule_locked(callout_impl_t *c, kmutex_t *lock, int to_ticks) 337callout_schedule_locked(callout_impl_t *c, kmutex_t *lock, int to_ticks)
339{ 338{
340 struct callout_cpu *cc, *occ; 339 struct callout_cpu *cc, *occ;
341 int old_time; 340 int old_time;
342 341
343 KASSERT(to_ticks >= 0); 342 KASSERT(to_ticks >= 0);
344 KASSERT(c->c_func != NULL); 343 KASSERT(c->c_func != NULL);
345 344
346 /* Initialize the time here, it won't change. */ 345 /* Initialize the time here, it won't change. */
347 occ = c->c_cpu; 346 occ = c->c_cpu;
348 c->c_flags &= ~(CALLOUT_FIRED | CALLOUT_INVOKING); 347 c->c_flags &= ~(CALLOUT_FIRED | CALLOUT_INVOKING);
349 348
350 /* 349 /*
351 * If this timeout is already scheduled and now is moved 350 * If this timeout is already scheduled and now is moved
352 * earlier, reschedule it now. Otherwise leave it in place 351 * earlier, reschedule it now. Otherwise leave it in place
353 * and let it be rescheduled later. 352 * and let it be rescheduled later.
354 */ 353 */
355 if ((c->c_flags & CALLOUT_PENDING) != 0) { 354 if ((c->c_flags & CALLOUT_PENDING) != 0) {
356 /* Leave on existing CPU. */ 355 /* Leave on existing CPU. */
357 old_time = c->c_time; 356 old_time = c->c_time;
358 c->c_time = to_ticks + occ->cc_ticks; 357 c->c_time = to_ticks + occ->cc_ticks;
359 if (c->c_time - old_time < 0) { 358 if (c->c_time - old_time < 0) {
360 CIRCQ_REMOVE(&c->c_list); 359 CIRCQ_REMOVE(&c->c_list);
361 CIRCQ_INSERT(&c->c_list, &occ->cc_todo); 360 CIRCQ_INSERT(&c->c_list, &occ->cc_todo);
362 } 361 }
363 mutex_spin_exit(lock); 362 mutex_spin_exit(lock);
364 return; 363 return;
365 } 364 }
366 365
367 cc = curcpu()->ci_data.cpu_callout; 366 cc = curcpu()->ci_data.cpu_callout;
368 if ((c->c_flags & CALLOUT_BOUND) != 0 || cc == occ || 367 if ((c->c_flags & CALLOUT_BOUND) != 0 || cc == occ ||
369 !mutex_tryenter(cc->cc_lock)) { 368 !mutex_tryenter(cc->cc_lock)) {
370 /* Leave on existing CPU. */ 369 /* Leave on existing CPU. */
371 c->c_time = to_ticks + occ->cc_ticks; 370 c->c_time = to_ticks + occ->cc_ticks;
372 c->c_flags |= CALLOUT_PENDING; 371 c->c_flags |= CALLOUT_PENDING;
373 CIRCQ_INSERT(&c->c_list, &occ->cc_todo); 372 CIRCQ_INSERT(&c->c_list, &occ->cc_todo);
374 } else { 373 } else {
375 /* Move to this CPU. */ 374 /* Move to this CPU. */
376 c->c_cpu = cc; 375 c->c_cpu = cc;
377 c->c_time = to_ticks + cc->cc_ticks; 376 c->c_time = to_ticks + cc->cc_ticks;
378 c->c_flags |= CALLOUT_PENDING; 377 c->c_flags |= CALLOUT_PENDING;
379 CIRCQ_INSERT(&c->c_list, &cc->cc_todo); 378 CIRCQ_INSERT(&c->c_list, &cc->cc_todo);
380 mutex_spin_exit(cc->cc_lock); 379 mutex_spin_exit(cc->cc_lock);
381 } 380 }
382 mutex_spin_exit(lock); 381 mutex_spin_exit(lock);
383} 382}
384 383
385/* 384/*
386 * callout_reset: 385 * callout_reset:
387 * 386 *
388 * Reset a callout structure with a new function and argument, and 387 * Reset a callout structure with a new function and argument, and
389 * schedule it to run. 388 * schedule it to run.
390 */ 389 */
391void 390void
392callout_reset(callout_t *cs, int to_ticks, void (*func)(void *), void *arg) 391callout_reset(callout_t *cs, int to_ticks, void (*func)(void *), void *arg)
393{ 392{
394 callout_impl_t *c = (callout_impl_t *)cs; 393 callout_impl_t *c = (callout_impl_t *)cs;
395 kmutex_t *lock; 394 kmutex_t *lock;
396 395
397 KASSERT(c->c_magic == CALLOUT_MAGIC); 396 KASSERT(c->c_magic == CALLOUT_MAGIC);
398 KASSERT(func != NULL); 397 KASSERT(func != NULL);
399 398
400 lock = callout_lock(c); 399 lock = callout_lock(c);
401 c->c_func = func; 400 c->c_func = func;
402 c->c_arg = arg; 401 c->c_arg = arg;
403 callout_schedule_locked(c, lock, to_ticks); 402 callout_schedule_locked(c, lock, to_ticks);
404} 403}
405 404
406/* 405/*
407 * callout_schedule: 406 * callout_schedule:
408 * 407 *
409 * Schedule a callout to run. The function and argument must 408 * Schedule a callout to run. The function and argument must
410 * already be set in the callout structure. 409 * already be set in the callout structure.
411 */ 410 */
412void 411void
413callout_schedule(callout_t *cs, int to_ticks) 412callout_schedule(callout_t *cs, int to_ticks)
414{ 413{
415 callout_impl_t *c = (callout_impl_t *)cs; 414 callout_impl_t *c = (callout_impl_t *)cs;
416 kmutex_t *lock; 415 kmutex_t *lock;
417 416
418 KASSERT(c->c_magic == CALLOUT_MAGIC); 417 KASSERT(c->c_magic == CALLOUT_MAGIC);
419 418
420 lock = callout_lock(c); 419 lock = callout_lock(c);
421 callout_schedule_locked(c, lock, to_ticks); 420 callout_schedule_locked(c, lock, to_ticks);
422} 421}
423 422
424/* 423/*
425 * callout_stop: 424 * callout_stop:
426 * 425 *
427 * Try to cancel a pending callout. It may be too late: the callout 426 * Try to cancel a pending callout. It may be too late: the callout
428 * could be running on another CPU. If called from interrupt context, 427 * could be running on another CPU. If called from interrupt context,
429 * the callout could already be in progress at a lower priority. 428 * the callout could already be in progress at a lower priority.
430 */ 429 */
431bool 430bool
432callout_stop(callout_t *cs) 431callout_stop(callout_t *cs)
433{ 432{
434 callout_impl_t *c = (callout_impl_t *)cs; 433 callout_impl_t *c = (callout_impl_t *)cs;
435 struct callout_cpu *cc; 434 struct callout_cpu *cc;
436 kmutex_t *lock; 435 kmutex_t *lock;
437 bool expired; 436 bool expired;
438 437
439 KASSERT(c->c_magic == CALLOUT_MAGIC); 438 KASSERT(c->c_magic == CALLOUT_MAGIC);
440 439
441 lock = callout_lock(c); 440 lock = callout_lock(c);
442 441
443 if ((c->c_flags & CALLOUT_PENDING) != 0) 442 if ((c->c_flags & CALLOUT_PENDING) != 0)
444 CIRCQ_REMOVE(&c->c_list); 443 CIRCQ_REMOVE(&c->c_list);
445 expired = ((c->c_flags & CALLOUT_FIRED) != 0); 444 expired = ((c->c_flags & CALLOUT_FIRED) != 0);
446 c->c_flags &= ~(CALLOUT_PENDING|CALLOUT_FIRED); 445 c->c_flags &= ~(CALLOUT_PENDING|CALLOUT_FIRED);
447 446
448 cc = c->c_cpu; 447 cc = c->c_cpu;
449 if (cc->cc_active == c) { 448 if (cc->cc_active == c) {
450 /* 449 /*
451 * This is for non-MPSAFE callouts only. To synchronize 450 * This is for non-MPSAFE callouts only. To synchronize
452 * effectively we must be called with kernel_lock held. 451 * effectively we must be called with kernel_lock held.
453 * It's also taken in callout_softclock. 452 * It's also taken in callout_softclock.
454 */ 453 */
455 cc->cc_cancel = c; 454 cc->cc_cancel = c;
456 } 455 }
457 456
458 mutex_spin_exit(lock); 457 mutex_spin_exit(lock);
459 458
460 return expired; 459 return expired;
461} 460}
462 461
463/* 462/*
464 * callout_halt: 463 * callout_halt:
465 * 464 *
466 * Cancel a pending callout. If in-flight, block until it completes. 465 * Cancel a pending callout. If in-flight, block until it completes.
467 * May not be called from a hard interrupt handler. If the callout 466 * May not be called from a hard interrupt handler. If the callout
468 * can take locks, the caller of callout_halt() must not hold any of 467 * can take locks, the caller of callout_halt() must not hold any of
469 * those locks, otherwise the two could deadlock. If 'interlock' is 468 * those locks, otherwise the two could deadlock. If 'interlock' is
470 * non-NULL and we must wait for the callout to complete, it will be 469 * non-NULL and we must wait for the callout to complete, it will be
471 * released and re-acquired before returning. 470 * released and re-acquired before returning.
472 */ 471 */
473bool 472bool
474callout_halt(callout_t *cs, void *interlock) 473callout_halt(callout_t *cs, void *interlock)
475{ 474{
476 callout_impl_t *c = (callout_impl_t *)cs; 475 callout_impl_t *c = (callout_impl_t *)cs;
477 kmutex_t *lock; 476 kmutex_t *lock;
478 int flags; 477 int flags;
479 478
480 KASSERT(c->c_magic == CALLOUT_MAGIC); 479 KASSERT(c->c_magic == CALLOUT_MAGIC);
481 KASSERT(!cpu_intr_p()); 480 KASSERT(!cpu_intr_p());
482 KASSERT(interlock == NULL || mutex_owned(interlock)); 481 KASSERT(interlock == NULL || mutex_owned(interlock));
483 482
484 /* Fast path. */ 483 /* Fast path. */
485 lock = callout_lock(c); 484 lock = callout_lock(c);
486 flags = c->c_flags; 485 flags = c->c_flags;
487 if ((flags & CALLOUT_PENDING) != 0) 486 if ((flags & CALLOUT_PENDING) != 0)
488 CIRCQ_REMOVE(&c->c_list); 487 CIRCQ_REMOVE(&c->c_list);
489 c->c_flags = flags & ~(CALLOUT_PENDING|CALLOUT_FIRED); 488 c->c_flags = flags & ~(CALLOUT_PENDING|CALLOUT_FIRED);
490 if (__predict_false(flags & CALLOUT_FIRED)) { 489 if (__predict_false(flags & CALLOUT_FIRED)) {
491 callout_wait(c, interlock, lock); 490 callout_wait(c, interlock, lock);
492 return true; 491 return true;
493 } 492 }
494 mutex_spin_exit(lock); 493 mutex_spin_exit(lock);
495 return false; 494 return false;
496} 495}
497 496
498/* 497/*
499 * callout_wait: 498 * callout_wait:
500 * 499 *
501 * Slow path for callout_halt(). Deliberately marked __noinline to 500 * Slow path for callout_halt(). Deliberately marked __noinline to
502 * prevent unneeded overhead in the caller. 501 * prevent unneeded overhead in the caller.
503 */ 502 */
504static void __noinline 503static void __noinline
505callout_wait(callout_impl_t *c, void *interlock, kmutex_t *lock) 504callout_wait(callout_impl_t *c, void *interlock, kmutex_t *lock)
506{ 505{
507 struct callout_cpu *cc; 506 struct callout_cpu *cc;
508 struct lwp *l; 507 struct lwp *l;
509 kmutex_t *relock; 508 kmutex_t *relock;
510 509
511 l = curlwp; 510 l = curlwp;
512 relock = NULL; 511 relock = NULL;
513 for (;;) { 512 for (;;) {
514 /* 513 /*
515 * At this point we know the callout is not pending, but it 514 * At this point we know the callout is not pending, but it
516 * could be running on a CPU somewhere. That can be curcpu 515 * could be running on a CPU somewhere. That can be curcpu
517 * in a few cases: 516 * in a few cases:
518 * 517 *
519 * - curlwp is a higher priority soft interrupt 518 * - curlwp is a higher priority soft interrupt
520 * - the callout blocked on a lock and is currently asleep 519 * - the callout blocked on a lock and is currently asleep
521 * - the callout itself has called callout_halt() (nice!) 520 * - the callout itself has called callout_halt() (nice!)
522 */ 521 */
523 cc = c->c_cpu; 522 cc = c->c_cpu;
524 if (__predict_true(cc->cc_active != c || cc->cc_lwp == l)) 523 if (__predict_true(cc->cc_active != c || cc->cc_lwp == l))
525 break; 524 break;
526 525
527 /* It's running - need to wait for it to complete. */ 526 /* It's running - need to wait for it to complete. */
528 if (interlock != NULL) { 527 if (interlock != NULL) {
529 /* 528 /*
530 * Avoid potential scheduler lock order problems by 529 * Avoid potential scheduler lock order problems by
531 * dropping the interlock without the callout lock 530 * dropping the interlock without the callout lock
532 * held; then retry. 531 * held; then retry.
533 */ 532 */
534 mutex_spin_exit(lock); 533 mutex_spin_exit(lock);
535 mutex_exit(interlock); 534 mutex_exit(interlock);
536 relock = interlock; 535 relock = interlock;
537 interlock = NULL; 536 interlock = NULL;
538 } else { 537 } else {
539 /* XXX Better to do priority inheritance. */ 538 /* XXX Better to do priority inheritance. */
540 KASSERT(l->l_wchan == NULL); 539 KASSERT(l->l_wchan == NULL);
541 cc->cc_nwait++; 540 cc->cc_nwait++;
542 cc->cc_ev_block.ev_count++; 541 cc->cc_ev_block.ev_count++;
543 l->l_kpriority = true; 542 l->l_kpriority = true;
544 sleepq_enter(&cc->cc_sleepq, l, cc->cc_lock); 543 sleepq_enter(&cc->cc_sleepq, l, cc->cc_lock);
545 sleepq_enqueue(&cc->cc_sleepq, cc, "callout", 544 sleepq_enqueue(&cc->cc_sleepq, cc, "callout",
546 &sleep_syncobj, false); 545 &sleep_syncobj, false);
547 sleepq_block(0, false); 546 sleepq_block(0, false);
548 } 547 }
549 548
550 /* 549 /*
551 * Re-lock the callout and check the state of play again.  550 * Re-lock the callout and check the state of play again.
552 * It's a common design pattern for callouts to re-schedule 551 * It's a common design pattern for callouts to re-schedule
553 * themselves so put a stop to it again if needed. 552 * themselves so put a stop to it again if needed.
554 */ 553 */
555 lock = callout_lock(c); 554 lock = callout_lock(c);
556 if ((c->c_flags & CALLOUT_PENDING) != 0) 555 if ((c->c_flags & CALLOUT_PENDING) != 0)
557 CIRCQ_REMOVE(&c->c_list); 556 CIRCQ_REMOVE(&c->c_list);
558 c->c_flags &= ~(CALLOUT_PENDING|CALLOUT_FIRED); 557 c->c_flags &= ~(CALLOUT_PENDING|CALLOUT_FIRED);
559 } 558 }
560 559
561 mutex_spin_exit(lock); 560 mutex_spin_exit(lock);
562 if (__predict_false(relock != NULL)) 561 if (__predict_false(relock != NULL))
563 mutex_enter(relock); 562 mutex_enter(relock);
564} 563}
565 564
566#ifdef notyet 565#ifdef notyet
567/* 566/*
568 * callout_bind: 567 * callout_bind:
569 * 568 *
570 * Bind a callout so that it will only execute on one CPU. 569 * Bind a callout so that it will only execute on one CPU.
571 * The callout must be stopped, and must be MPSAFE. 570 * The callout must be stopped, and must be MPSAFE.
572 * 571 *
573 * XXX Disabled for now until it is decided how to handle 572 * XXX Disabled for now until it is decided how to handle
574 * offlined CPUs. We may want weak+strong binding. 573 * offlined CPUs. We may want weak+strong binding.
575 */ 574 */
576void 575void
577callout_bind(callout_t *cs, struct cpu_info *ci) 576callout_bind(callout_t *cs, struct cpu_info *ci)
578{ 577{
579 callout_impl_t *c = (callout_impl_t *)cs; 578 callout_impl_t *c = (callout_impl_t *)cs;
580 struct callout_cpu *cc; 579 struct callout_cpu *cc;
581 kmutex_t *lock; 580 kmutex_t *lock;
582 581
583 KASSERT((c->c_flags & CALLOUT_PENDING) == 0); 582 KASSERT((c->c_flags & CALLOUT_PENDING) == 0);
584 KASSERT(c->c_cpu->cc_active != c); 583 KASSERT(c->c_cpu->cc_active != c);
585 KASSERT(c->c_magic == CALLOUT_MAGIC); 584 KASSERT(c->c_magic == CALLOUT_MAGIC);
586 KASSERT((c->c_flags & CALLOUT_MPSAFE) != 0); 585 KASSERT((c->c_flags & CALLOUT_MPSAFE) != 0);
587 586
588 lock = callout_lock(c); 587 lock = callout_lock(c);
589 cc = ci->ci_data.cpu_callout; 588 cc = ci->ci_data.cpu_callout;
590 c->c_flags |= CALLOUT_BOUND; 589 c->c_flags |= CALLOUT_BOUND;
591 if (c->c_cpu != cc) { 590 if (c->c_cpu != cc) {
592 /* 591 /*
593 * Assigning c_cpu effectively unlocks the callout 592 * Assigning c_cpu effectively unlocks the callout
594 * structure, as we don't hold the new CPU's lock. 593 * structure, as we don't hold the new CPU's lock.
595 * Issue memory barrier to prevent accesses being 594 * Issue memory barrier to prevent accesses being
596 * reordered. 595 * reordered.
597 */ 596 */
598 membar_exit(); 597 membar_exit();
599 c->c_cpu = cc; 598 c->c_cpu = cc;
600 } 599 }
601 mutex_spin_exit(lock); 600 mutex_spin_exit(lock);
602} 601}
603#endif 602#endif
604 603
605void 604void
606callout_setfunc(callout_t *cs, void (*func)(void *), void *arg) 605callout_setfunc(callout_t *cs, void (*func)(void *), void *arg)
607{ 606{
608 callout_impl_t *c = (callout_impl_t *)cs; 607 callout_impl_t *c = (callout_impl_t *)cs;
609 kmutex_t *lock; 608 kmutex_t *lock;
610 609
611 KASSERT(c->c_magic == CALLOUT_MAGIC); 610 KASSERT(c->c_magic == CALLOUT_MAGIC);
612 KASSERT(func != NULL); 611 KASSERT(func != NULL);
613 612
614 lock = callout_lock(c); 613 lock = callout_lock(c);
615 c->c_func = func; 614 c->c_func = func;
616 c->c_arg = arg; 615 c->c_arg = arg;
617 mutex_spin_exit(lock); 616 mutex_spin_exit(lock);
618} 617}
619 618
620bool 619bool
621callout_expired(callout_t *cs) 620callout_expired(callout_t *cs)
622{ 621{
623 callout_impl_t *c = (callout_impl_t *)cs; 622 callout_impl_t *c = (callout_impl_t *)cs;
624 kmutex_t *lock; 623 kmutex_t *lock;
625 bool rv; 624 bool rv;
626 625
627 KASSERT(c->c_magic == CALLOUT_MAGIC); 626 KASSERT(c->c_magic == CALLOUT_MAGIC);
628 627
629 lock = callout_lock(c); 628 lock = callout_lock(c);
630 rv = ((c->c_flags & CALLOUT_FIRED) != 0); 629 rv = ((c->c_flags & CALLOUT_FIRED) != 0);
631 mutex_spin_exit(lock); 630 mutex_spin_exit(lock);
632 631
633 return rv; 632 return rv;
634} 633}
635 634
636bool 635bool
637callout_active(callout_t *cs) 636callout_active(callout_t *cs)
638{ 637{
639 callout_impl_t *c = (callout_impl_t *)cs; 638 callout_impl_t *c = (callout_impl_t *)cs;
640 kmutex_t *lock; 639 kmutex_t *lock;
641 bool rv; 640 bool rv;
642 641
643 KASSERT(c->c_magic == CALLOUT_MAGIC); 642 KASSERT(c->c_magic == CALLOUT_MAGIC);
644 643
645 lock = callout_lock(c); 644 lock = callout_lock(c);
646 rv = ((c->c_flags & (CALLOUT_PENDING|CALLOUT_FIRED)) != 0); 645 rv = ((c->c_flags & (CALLOUT_PENDING|CALLOUT_FIRED)) != 0);
647 mutex_spin_exit(lock); 646 mutex_spin_exit(lock);
648 647
649 return rv; 648 return rv;
650} 649}
651 650
652bool 651bool
653callout_pending(callout_t *cs) 652callout_pending(callout_t *cs)
654{ 653{
655 callout_impl_t *c = (callout_impl_t *)cs; 654 callout_impl_t *c = (callout_impl_t *)cs;
656 kmutex_t *lock; 655 kmutex_t *lock;
657 bool rv; 656 bool rv;
658 657
659 KASSERT(c->c_magic == CALLOUT_MAGIC); 658 KASSERT(c->c_magic == CALLOUT_MAGIC);
660 659
661 lock = callout_lock(c); 660 lock = callout_lock(c);
662 rv = ((c->c_flags & CALLOUT_PENDING) != 0); 661 rv = ((c->c_flags & CALLOUT_PENDING) != 0);
663 mutex_spin_exit(lock); 662 mutex_spin_exit(lock);
664 663
665 return rv; 664 return rv;
666} 665}
667 666
668bool 667bool
669callout_invoking(callout_t *cs) 668callout_invoking(callout_t *cs)
670{ 669{
671 callout_impl_t *c = (callout_impl_t *)cs; 670 callout_impl_t *c = (callout_impl_t *)cs;
672 kmutex_t *lock; 671 kmutex_t *lock;
673 bool rv; 672 bool rv;
674 673
675 KASSERT(c->c_magic == CALLOUT_MAGIC); 674 KASSERT(c->c_magic == CALLOUT_MAGIC);
676 675
677 lock = callout_lock(c); 676 lock = callout_lock(c);
678 rv = ((c->c_flags & CALLOUT_INVOKING) != 0); 677 rv = ((c->c_flags & CALLOUT_INVOKING) != 0);
679 mutex_spin_exit(lock); 678 mutex_spin_exit(lock);
680 679
681 return rv; 680 return rv;
682} 681}
683 682
684void 683void
685callout_ack(callout_t *cs) 684callout_ack(callout_t *cs)
686{ 685{
687 callout_impl_t *c = (callout_impl_t *)cs; 686 callout_impl_t *c = (callout_impl_t *)cs;
688 kmutex_t *lock; 687 kmutex_t *lock;
689 688
690 KASSERT(c->c_magic == CALLOUT_MAGIC); 689 KASSERT(c->c_magic == CALLOUT_MAGIC);
691 690
692 lock = callout_lock(c); 691 lock = callout_lock(c);
693 c->c_flags &= ~CALLOUT_INVOKING; 692 c->c_flags &= ~CALLOUT_INVOKING;
694 mutex_spin_exit(lock); 693 mutex_spin_exit(lock);
695} 694}
696 695
697/* 696/*
698 * callout_hardclock: 697 * callout_hardclock:
699 * 698 *
700 * Called from hardclock() once every tick. We schedule a soft 699 * Called from hardclock() once every tick. We schedule a soft
701 * interrupt if there is work to be done. 700 * interrupt if there is work to be done.
702 */ 701 */
703void 702void
704callout_hardclock(void) 703callout_hardclock(void)
705{ 704{
706 struct callout_cpu *cc; 705 struct callout_cpu *cc;
707 int needsoftclock, ticks; 706 int needsoftclock, ticks;
708 707
709 cc = curcpu()->ci_data.cpu_callout; 708 cc = curcpu()->ci_data.cpu_callout;
710 mutex_spin_enter(cc->cc_lock); 709 mutex_spin_enter(cc->cc_lock);
711 710
712 ticks = ++cc->cc_ticks; 711 ticks = ++cc->cc_ticks;
713 712
714 MOVEBUCKET(cc, 0, ticks); 713 MOVEBUCKET(cc, 0, ticks);
715 if (MASKWHEEL(0, ticks) == 0) { 714 if (MASKWHEEL(0, ticks) == 0) {
716 MOVEBUCKET(cc, 1, ticks); 715 MOVEBUCKET(cc, 1, ticks);
717 if (MASKWHEEL(1, ticks) == 0) { 716 if (MASKWHEEL(1, ticks) == 0) {
718 MOVEBUCKET(cc, 2, ticks); 717 MOVEBUCKET(cc, 2, ticks);
719 if (MASKWHEEL(2, ticks) == 0) 718 if (MASKWHEEL(2, ticks) == 0)
720 MOVEBUCKET(cc, 3, ticks); 719 MOVEBUCKET(cc, 3, ticks);
721 } 720 }
722 } 721 }
723 722
724 needsoftclock = !CIRCQ_EMPTY(&cc->cc_todo); 723 needsoftclock = !CIRCQ_EMPTY(&cc->cc_todo);
725 mutex_spin_exit(cc->cc_lock); 724 mutex_spin_exit(cc->cc_lock);
726 725
727 if (needsoftclock) 726 if (needsoftclock)
728 softint_schedule(callout_sih); 727 softint_schedule(callout_sih);
729} 728}
730 729
731/* 730/*
732 * callout_softclock: 731 * callout_softclock:
733 * 732 *
734 * Soft interrupt handler, scheduled above if there is work to 733 * Soft interrupt handler, scheduled above if there is work to
735 * be done. Callouts are made in soft interrupt context. 734 * be done. Callouts are made in soft interrupt context.
736 */ 735 */
737static void 736static void
738callout_softclock(void *v) 737callout_softclock(void *v)
739{ 738{
740 callout_impl_t *c; 739 callout_impl_t *c;
741 struct callout_cpu *cc; 740 struct callout_cpu *cc;
742 void (*func)(void *); 741 void (*func)(void *);
743 void *arg; 742 void *arg;
744 int mpsafe, count, ticks, delta; 743 int mpsafe, count, ticks, delta;
745 lwp_t *l; 744 lwp_t *l;
746 745
747 l = curlwp; 746 l = curlwp;
748 KASSERT(l->l_cpu == curcpu()); 747 KASSERT(l->l_cpu == curcpu());
749 cc = l->l_cpu->ci_data.cpu_callout; 748 cc = l->l_cpu->ci_data.cpu_callout;
750 749
751 mutex_spin_enter(cc->cc_lock); 750 mutex_spin_enter(cc->cc_lock);
752 cc->cc_lwp = l; 751 cc->cc_lwp = l;
753 while (!CIRCQ_EMPTY(&cc->cc_todo)) { 752 while (!CIRCQ_EMPTY(&cc->cc_todo)) {
754 c = CIRCQ_FIRST(&cc->cc_todo); 753 c = CIRCQ_FIRST(&cc->cc_todo);
755 KASSERT(c->c_magic == CALLOUT_MAGIC); 754 KASSERT(c->c_magic == CALLOUT_MAGIC);
756 KASSERT(c->c_func != NULL); 755 KASSERT(c->c_func != NULL);
757 KASSERT(c->c_cpu == cc); 756 KASSERT(c->c_cpu == cc);
758 KASSERT((c->c_flags & CALLOUT_PENDING) != 0); 757 KASSERT((c->c_flags & CALLOUT_PENDING) != 0);
759 KASSERT((c->c_flags & CALLOUT_FIRED) == 0); 758 KASSERT((c->c_flags & CALLOUT_FIRED) == 0);
760 CIRCQ_REMOVE(&c->c_list); 759 CIRCQ_REMOVE(&c->c_list);
761 760
762 /* If due run it, otherwise insert it into the right bucket. */ 761 /* If due run it, otherwise insert it into the right bucket. */
763 ticks = cc->cc_ticks; 762 ticks = cc->cc_ticks;
764 delta = (int)((unsigned)c->c_time - (unsigned)ticks); 763 delta = (int)((unsigned)c->c_time - (unsigned)ticks);
765 if (delta > 0) { 764 if (delta > 0) {
766 CIRCQ_INSERT(&c->c_list, BUCKET(cc, delta, c->c_time)); 765 CIRCQ_INSERT(&c->c_list, BUCKET(cc, delta, c->c_time));
767 continue; 766 continue;
768 } 767 }
769 if (delta < 0) 768 if (delta < 0)
770 cc->cc_ev_late.ev_count++; 769 cc->cc_ev_late.ev_count++;
771 770
772 c->c_flags = (c->c_flags & ~CALLOUT_PENDING) | 771 c->c_flags = (c->c_flags & ~CALLOUT_PENDING) |
773 (CALLOUT_FIRED | CALLOUT_INVOKING); 772 (CALLOUT_FIRED | CALLOUT_INVOKING);
774 mpsafe = (c->c_flags & CALLOUT_MPSAFE); 773 mpsafe = (c->c_flags & CALLOUT_MPSAFE);
775 func = c->c_func; 774 func = c->c_func;
776 arg = c->c_arg; 775 arg = c->c_arg;
777 cc->cc_active = c; 776 cc->cc_active = c;
778 777
779 mutex_spin_exit(cc->cc_lock); 778 mutex_spin_exit(cc->cc_lock);
780 KASSERT(func != NULL); 779 KASSERT(func != NULL);
781 if (__predict_false(!mpsafe)) { 780 if (__predict_false(!mpsafe)) {
782 KERNEL_LOCK(1, NULL); 781 KERNEL_LOCK(1, NULL);
783 (*func)(arg); 782 (*func)(arg);
784 KERNEL_UNLOCK_ONE(NULL); 783 KERNEL_UNLOCK_ONE(NULL);
785 } else 784 } else
786 (*func)(arg); 785 (*func)(arg);
787 mutex_spin_enter(cc->cc_lock); 786 mutex_spin_enter(cc->cc_lock);
788 787
789 /* 788 /*
790 * We can't touch 'c' here because it might be 789 * We can't touch 'c' here because it might be
791 * freed already. If LWPs waiting for callout 790 * freed already. If LWPs waiting for callout
792 * to complete, awaken them. 791 * to complete, awaken them.
793 */ 792 */
794 cc->cc_active = NULL; 793 cc->cc_active = NULL;
795 if ((count = cc->cc_nwait) != 0) { 794 if ((count = cc->cc_nwait) != 0) {
796 cc->cc_nwait = 0; 795 cc->cc_nwait = 0;
797 /* sleepq_wake() drops the lock. */ 796 /* sleepq_wake() drops the lock. */
798 sleepq_wake(&cc->cc_sleepq, cc, count, cc->cc_lock); 797 sleepq_wake(&cc->cc_sleepq, cc, count, cc->cc_lock);
799 mutex_spin_enter(cc->cc_lock); 798 mutex_spin_enter(cc->cc_lock);
800 } 799 }
801 } 800 }
802 cc->cc_lwp = NULL; 801 cc->cc_lwp = NULL;
803 mutex_spin_exit(cc->cc_lock); 802 mutex_spin_exit(cc->cc_lock);
804} 803}
805#endif /* !CRASH */ 804#endif /* !CRASH */
806 805
807#ifdef DDB 806#ifdef DDB
808static void 807static void
809db_show_callout_bucket(struct callout_cpu *cc, struct callout_circq *kbucket, 808db_show_callout_bucket(struct callout_cpu *cc, struct callout_circq *kbucket,
810 struct callout_circq *bucket) 809 struct callout_circq *bucket)
811{ 810{
812 callout_impl_t *c, ci; 811 callout_impl_t *c, ci;
813 db_expr_t offset; 812 db_expr_t offset;
814 const char *name; 813 const char *name;
815 static char question[] = "?"; 814 static char question[] = "?";
816 int b; 815 int b;
817 816
818 if (CIRCQ_LAST(bucket, kbucket)) 817 if (CIRCQ_LAST(bucket, kbucket))
819 return; 818 return;
820 819
821 for (c = CIRCQ_FIRST(bucket); /*nothing*/; c = CIRCQ_NEXT(&c->c_list)) { 820 for (c = CIRCQ_FIRST(bucket); /*nothing*/; c = CIRCQ_NEXT(&c->c_list)) {
822 db_read_bytes((db_addr_t)c, sizeof(ci), (char *)&ci); 821 db_read_bytes((db_addr_t)c, sizeof(ci), (char *)&ci);
823 c = &ci; 822 c = &ci;
824 db_find_sym_and_offset((db_addr_t)(intptr_t)c->c_func, &name, 823 db_find_sym_and_offset((db_addr_t)(intptr_t)c->c_func, &name,
825 &offset); 824 &offset);
826 name = name ? name : question; 825 name = name ? name : question;
827 b = (bucket - cc->cc_wheel); 826 b = (bucket - cc->cc_wheel);
828 if (b < 0) 827 if (b < 0)
829 b = -WHEELSIZE; 828 b = -WHEELSIZE;
830 db_printf("%9d %2d/%-4d %16lx %s\n", 829 db_printf("%9d %2d/%-4d %16lx %s\n",
831 c->c_time - cc->cc_ticks, b / WHEELSIZE, b, 830 c->c_time - cc->cc_ticks, b / WHEELSIZE, b,
832 (u_long)c->c_arg, name); 831 (u_long)c->c_arg, name);
833 if (CIRCQ_LAST(&c->c_list, kbucket)) 832 if (CIRCQ_LAST(&c->c_list, kbucket))
834 break; 833 break;
835 } 834 }
836} 835}
837 836
838void 837void
839db_show_callout(db_expr_t addr, bool haddr, db_expr_t count, const char *modif) 838db_show_callout(db_expr_t addr, bool haddr, db_expr_t count, const char *modif)
840{ 839{
841 struct callout_cpu *cc; 840 struct callout_cpu *cc;
842 struct cpu_info *ci; 841 struct cpu_info *ci;
843 int b; 842 int b;
844 843
845#ifndef CRASH 844#ifndef CRASH
846 db_printf("hardclock_ticks now: %d\n", getticks()); 845 db_printf("hardclock_ticks now: %d\n", getticks());
847#endif 846#endif
848 db_printf(" ticks wheel arg func\n"); 847 db_printf(" ticks wheel arg func\n");
849 848
850 /* 849 /*
851 * Don't lock the callwheel; all the other CPUs are paused 850 * Don't lock the callwheel; all the other CPUs are paused
852 * anyhow, and we might be called in a circumstance where 851 * anyhow, and we might be called in a circumstance where
853 * some other CPU was paused while holding the lock. 852 * some other CPU was paused while holding the lock.
854 */ 853 */
855 for (ci = db_cpu_first(); ci != NULL; ci = db_cpu_next(ci)) { 854 for (ci = db_cpu_first(); ci != NULL; ci = db_cpu_next(ci)) {
856 db_read_bytes((db_addr_t)ci, sizeof(cib), (char *)&cib); 855 db_read_bytes((db_addr_t)ci +
857 cc = cib.ci_data.cpu_callout; 856 offsetof(struct cpu_info, ci_data.cpu_callout),
 857 sizeof(cc), (char *)&cc);
858 db_read_bytes((db_addr_t)cc, sizeof(ccb), (char *)&ccb); 858 db_read_bytes((db_addr_t)cc, sizeof(ccb), (char *)&ccb);
859 db_show_callout_bucket(&ccb, &cc->cc_todo, &ccb.cc_todo); 859 db_show_callout_bucket(&ccb, &cc->cc_todo, &ccb.cc_todo);
860 } 860 }
861 for (b = 0; b < BUCKETS; b++) { 861 for (b = 0; b < BUCKETS; b++) {
862 for (ci = db_cpu_first(); ci != NULL; ci = db_cpu_next(ci)) { 862 for (ci = db_cpu_first(); ci != NULL; ci = db_cpu_next(ci)) {
863 db_read_bytes((db_addr_t)ci, sizeof(cib), (char *)&cib); 863 db_read_bytes((db_addr_t)ci +
864 cc = cib.ci_data.cpu_callout; 864 offsetof(struct cpu_info, ci_data.cpu_callout),
 865 sizeof(cc), (char *)&cc);
865 db_read_bytes((db_addr_t)cc, sizeof(ccb), (char *)&ccb); 866 db_read_bytes((db_addr_t)cc, sizeof(ccb), (char *)&ccb);
866 db_show_callout_bucket(&ccb, &cc->cc_wheel[b], 867 db_show_callout_bucket(&ccb, &cc->cc_wheel[b],
867 &ccb.cc_wheel[b]); 868 &ccb.cc_wheel[b]);
868 } 869 }
869 } 870 }
870} 871}
871#endif /* DDB */ 872#endif /* DDB */