1a9643ea8Slogwang /*-
2a9643ea8Slogwang * Copyright (c) 1982, 1986, 1991, 1993
3a9643ea8Slogwang * The Regents of the University of California. All rights reserved.
4a9643ea8Slogwang * (c) UNIX System Laboratories, Inc.
5a9643ea8Slogwang * All or some portions of this file are derived from material licensed
6a9643ea8Slogwang * to the University of California by American Telephone and Telegraph
7a9643ea8Slogwang * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8a9643ea8Slogwang * the permission of UNIX System Laboratories, Inc.
9a9643ea8Slogwang *
10a9643ea8Slogwang * Copyright (c) 2010 Kip Macy. All rights reserved.
11a9643ea8Slogwang * Copyright (c) 2013 Patrick Kelsey. All rights reserved.
12*2317ada5Sfengbojiang * Copyright (C) 2017-2021 THL A29 Limited, a Tencent company.
13a9643ea8Slogwang * All rights reserved.
14a9643ea8Slogwang *
15a9643ea8Slogwang * Redistribution and use in source and binary forms, with or without
16a9643ea8Slogwang * modification, are permitted provided that the following conditions
17a9643ea8Slogwang * are met:
18a9643ea8Slogwang * 1. Redistributions of source code must retain the above copyright
19a9643ea8Slogwang * notice, this list of conditions and the following disclaimer.
20a9643ea8Slogwang * 2. Redistributions in binary form must reproduce the above copyright
21a9643ea8Slogwang * notice, this list of conditions and the following disclaimer in the
22a9643ea8Slogwang * documentation and/or other materials provided with the distribution.
23a9643ea8Slogwang * 4. Neither the name of the University nor the names of its contributors
24a9643ea8Slogwang * may be used to endorse or promote products derived from this software
25a9643ea8Slogwang * without specific prior written permission.
26a9643ea8Slogwang *
27a9643ea8Slogwang * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28a9643ea8Slogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29a9643ea8Slogwang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30a9643ea8Slogwang * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31a9643ea8Slogwang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32a9643ea8Slogwang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33a9643ea8Slogwang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34a9643ea8Slogwang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35a9643ea8Slogwang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36a9643ea8Slogwang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37a9643ea8Slogwang * SUCH DAMAGE.
38a9643ea8Slogwang *
39a9643ea8Slogwang * From: @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
40a9643ea8Slogwang *
41a9643ea8Slogwang * Derived in part from libplebnet's pn_kern_timeout.c and libuinet's uinet_timecounter.c.
42a9643ea8Slogwang *
43a9643ea8Slogwang */
44a9643ea8Slogwang
45a9643ea8Slogwang #include <sys/cdefs.h>
46a9643ea8Slogwang __FBSDID("$FreeBSD$");
47a9643ea8Slogwang
48a9643ea8Slogwang #include "opt_callout_profiling.h"
49a9643ea8Slogwang #include "opt_ddb.h"
50a9643ea8Slogwang #if defined(__arm__)
51a9643ea8Slogwang #include "opt_timer.h"
52a9643ea8Slogwang #endif
53a9643ea8Slogwang #include "opt_rss.h"
54a9643ea8Slogwang
55a9643ea8Slogwang #include <sys/param.h>
56a9643ea8Slogwang #include <sys/systm.h>
57a9643ea8Slogwang #include <sys/bus.h>
58a9643ea8Slogwang #include <sys/callout.h>
59a9643ea8Slogwang #include <sys/file.h>
60a9643ea8Slogwang #include <sys/interrupt.h>
61a9643ea8Slogwang #include <sys/kernel.h>
62a9643ea8Slogwang #include <sys/ktr.h>
63a9643ea8Slogwang #include <sys/lock.h>
64a9643ea8Slogwang #include <sys/malloc.h>
65a9643ea8Slogwang #include <sys/mutex.h>
66a9643ea8Slogwang #include <sys/proc.h>
67a9643ea8Slogwang #include <sys/sdt.h>
68a9643ea8Slogwang #include <sys/sleepqueue.h>
69a9643ea8Slogwang #include <sys/sysctl.h>
70a9643ea8Slogwang #include <sys/smp.h>
71a9643ea8Slogwang #include <sys/timetc.h>
72a9643ea8Slogwang
73a9643ea8Slogwang SDT_PROVIDER_DEFINE(callout_execute);
74a9643ea8Slogwang SDT_PROBE_DEFINE1(callout_execute, , , callout__start, "struct callout *");
75a9643ea8Slogwang SDT_PROBE_DEFINE1(callout_execute, , , callout__end, "struct callout *");
76a9643ea8Slogwang
77a9643ea8Slogwang #ifdef CALLOUT_PROFILING
78a9643ea8Slogwang static int avg_depth;
79a9643ea8Slogwang SYSCTL_INT(_debug, OID_AUTO, to_avg_depth, CTLFLAG_RD, &avg_depth, 0,
80a9643ea8Slogwang "Average number of items examined per softclock call. Units = 1/1000");
81a9643ea8Slogwang static int avg_gcalls;
82a9643ea8Slogwang SYSCTL_INT(_debug, OID_AUTO, to_avg_gcalls, CTLFLAG_RD, &avg_gcalls, 0,
83a9643ea8Slogwang "Average number of Giant callouts made per softclock call. Units = 1/1000");
84a9643ea8Slogwang static int avg_lockcalls;
85a9643ea8Slogwang SYSCTL_INT(_debug, OID_AUTO, to_avg_lockcalls, CTLFLAG_RD, &avg_lockcalls, 0,
86a9643ea8Slogwang "Average number of lock callouts made per softclock call. Units = 1/1000");
87a9643ea8Slogwang static int avg_mpcalls;
88a9643ea8Slogwang SYSCTL_INT(_debug, OID_AUTO, to_avg_mpcalls, CTLFLAG_RD, &avg_mpcalls, 0,
89a9643ea8Slogwang "Average number of MP callouts made per softclock call. Units = 1/1000");
90a9643ea8Slogwang #endif
91a9643ea8Slogwang
92a9643ea8Slogwang static int ncallout;
93a9643ea8Slogwang SYSCTL_INT(_kern, OID_AUTO, ncallout, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &ncallout, 0,
94a9643ea8Slogwang "Number of entries in callwheel and size of timeout() preallocation");
95a9643ea8Slogwang
96a9643ea8Slogwang #ifdef RSS
97a9643ea8Slogwang static int pin_default_swi = 1;
98a9643ea8Slogwang static int pin_pcpu_swi = 1;
99a9643ea8Slogwang #else
100a9643ea8Slogwang static int pin_default_swi = 0;
101a9643ea8Slogwang static int pin_pcpu_swi = 0;
102a9643ea8Slogwang #endif
103a9643ea8Slogwang
104a9643ea8Slogwang SYSCTL_INT(_kern, OID_AUTO, pin_default_swi, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &pin_default_swi,
105a9643ea8Slogwang 0, "Pin the default (non-per-cpu) swi (shared with PCPU 0 swi)");
106a9643ea8Slogwang SYSCTL_INT(_kern, OID_AUTO, pin_pcpu_swi, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &pin_pcpu_swi,
107a9643ea8Slogwang 0, "Pin the per-CPU swis (except PCPU 0, which is also default");
108a9643ea8Slogwang
109a9643ea8Slogwang #define sleepq_lock(w) do {} while(0)
110a9643ea8Slogwang #define sleepq_release(w) do {} while(0)
111a9643ea8Slogwang #define sleepq_add(a, b, c, d, e) do {} while(0)
112a9643ea8Slogwang #define sleepq_wait(w, p) do {} while(0)
113a9643ea8Slogwang
1145e5c25c3Slogwang #define CC_HASH_SHIFT 8
1155e5c25c3Slogwang
116a9643ea8Slogwang /*
117a9643ea8Slogwang * TODO:
118a9643ea8Slogwang * allocate more timeout table slots when table overflows.
119a9643ea8Slogwang */
120a9643ea8Slogwang u_int callwheelsize, callwheelmask;
121a9643ea8Slogwang
122a9643ea8Slogwang /*
123a9643ea8Slogwang * The callout cpu exec entities represent informations necessary for
124a9643ea8Slogwang * describing the state of callouts currently running on the CPU and the ones
125a9643ea8Slogwang * necessary for migrating callouts to the new callout cpu. In particular,
126a9643ea8Slogwang * the first entry of the array cc_exec_entity holds informations for callout
127a9643ea8Slogwang * running in SWI thread context, while the second one holds informations
128a9643ea8Slogwang * for callout running directly from hardware interrupt context.
129a9643ea8Slogwang * The cached informations are very important for deferring migration when
130a9643ea8Slogwang * the migrating callout is already running.
131a9643ea8Slogwang */
132a9643ea8Slogwang struct cc_exec {
133a9643ea8Slogwang struct callout *cc_curr;
134a9643ea8Slogwang void (*cc_drain)(void *);
135a9643ea8Slogwang bool cc_cancel;
136a9643ea8Slogwang bool cc_waiting;
137a9643ea8Slogwang };
138a9643ea8Slogwang
139a9643ea8Slogwang /*
140a9643ea8Slogwang * There is one struct callout_cpu per cpu, holding all relevant
141a9643ea8Slogwang * state for the callout processing thread on the individual CPU.
142a9643ea8Slogwang */
143a9643ea8Slogwang struct callout_cpu {
144a9643ea8Slogwang struct mtx_padalign cc_lock;
145a9643ea8Slogwang struct cc_exec cc_exec_entity[2];
146a9643ea8Slogwang struct callout *cc_next;
147a9643ea8Slogwang struct callout *cc_callout;
148a9643ea8Slogwang struct callout_list *cc_callwheel;
149a9643ea8Slogwang struct callout_tailq cc_expireq;
150a9643ea8Slogwang struct callout_slist cc_callfree;
1515e5c25c3Slogwang int cc_softticks;
152a9643ea8Slogwang void *cc_cookie;
153a9643ea8Slogwang u_int cc_bucket;
154a9643ea8Slogwang u_int cc_inited;
155a9643ea8Slogwang char cc_ktr_event_name[20];
156a9643ea8Slogwang };
157a9643ea8Slogwang
158a9643ea8Slogwang #define callout_migrating(c) ((c)->c_iflags & CALLOUT_DFRMIGRATION)
159a9643ea8Slogwang
160a9643ea8Slogwang #define cc_exec_curr(cc, dir) cc->cc_exec_entity[dir].cc_curr
161a9643ea8Slogwang #define cc_exec_drain(cc, dir) cc->cc_exec_entity[dir].cc_drain
162a9643ea8Slogwang #define cc_exec_next(cc) cc->cc_next
163a9643ea8Slogwang #define cc_exec_cancel(cc, dir) cc->cc_exec_entity[dir].cc_cancel
164a9643ea8Slogwang #define cc_exec_waiting(cc, dir) cc->cc_exec_entity[dir].cc_waiting
165a9643ea8Slogwang struct callout_cpu cc_cpu;
166a9643ea8Slogwang #define CC_CPU(cpu) &cc_cpu
167a9643ea8Slogwang #define CC_SELF() &cc_cpu
168a9643ea8Slogwang #define CC_LOCK(cc) mtx_lock_spin(&(cc)->cc_lock)
169a9643ea8Slogwang #define CC_UNLOCK(cc) mtx_unlock_spin(&(cc)->cc_lock)
170a9643ea8Slogwang #define CC_LOCK_ASSERT(cc) mtx_assert(&(cc)->cc_lock, MA_OWNED)
171a9643ea8Slogwang
172a9643ea8Slogwang static int timeout_cpu;
173a9643ea8Slogwang
174a9643ea8Slogwang static void callout_cpu_init(struct callout_cpu *cc, int cpu);
175a9643ea8Slogwang static void softclock_call_cc(struct callout *c, struct callout_cpu *cc,
176a9643ea8Slogwang #ifdef CALLOUT_PROFILING
177a9643ea8Slogwang int *mpcalls, int *lockcalls, int *gcalls,
178a9643ea8Slogwang #endif
179a9643ea8Slogwang int direct);
180a9643ea8Slogwang
181a9643ea8Slogwang static MALLOC_DEFINE(M_CALLOUT, "callout", "Callout datastructures");
182a9643ea8Slogwang
183a9643ea8Slogwang /**
184a9643ea8Slogwang * Locked by cc_lock:
185a9643ea8Slogwang * cc_curr - If a callout is in progress, it is cc_curr.
186a9643ea8Slogwang * If cc_curr is non-NULL, threads waiting in
187a9643ea8Slogwang * callout_drain() will be woken up as soon as the
188a9643ea8Slogwang * relevant callout completes.
189a9643ea8Slogwang * cc_cancel - Changing to 1 with both callout_lock and cc_lock held
190a9643ea8Slogwang * guarantees that the current callout will not run.
191a9643ea8Slogwang * The softclock() function sets this to 0 before it
192a9643ea8Slogwang * drops callout_lock to acquire c_lock, and it calls
193a9643ea8Slogwang * the handler only if curr_cancelled is still 0 after
194a9643ea8Slogwang * cc_lock is successfully acquired.
195a9643ea8Slogwang * cc_waiting - If a thread is waiting in callout_drain(), then
196a9643ea8Slogwang * callout_wait is nonzero. Set only when
197a9643ea8Slogwang * cc_curr is non-NULL.
198a9643ea8Slogwang */
199a9643ea8Slogwang
200a9643ea8Slogwang /*
201a9643ea8Slogwang * Resets the execution entity tied to a specific callout cpu.
202a9643ea8Slogwang */
203a9643ea8Slogwang static void
cc_cce_cleanup(struct callout_cpu * cc,int direct)204a9643ea8Slogwang cc_cce_cleanup(struct callout_cpu *cc, int direct)
205a9643ea8Slogwang {
206a9643ea8Slogwang cc_exec_curr(cc, direct) = NULL;
207a9643ea8Slogwang cc_exec_cancel(cc, direct) = false;
208a9643ea8Slogwang cc_exec_waiting(cc, direct) = false;
209a9643ea8Slogwang }
210a9643ea8Slogwang
211a9643ea8Slogwang /*
212a9643ea8Slogwang * Checks if migration is requested by a specific callout cpu.
213a9643ea8Slogwang */
214a9643ea8Slogwang static int
cc_cce_migrating(struct callout_cpu * cc,int direct)215a9643ea8Slogwang cc_cce_migrating(struct callout_cpu *cc, int direct)
216a9643ea8Slogwang {
217a9643ea8Slogwang return (0);
218a9643ea8Slogwang }
219a9643ea8Slogwang
220a9643ea8Slogwang /*
221a9643ea8Slogwang * Kernel low level callwheel initialization
222a9643ea8Slogwang * called on cpu0 during kernel startup.
223a9643ea8Slogwang */
224a9643ea8Slogwang static void
callout_callwheel_init(void * dummy)225a9643ea8Slogwang callout_callwheel_init(void *dummy)
226a9643ea8Slogwang {
227a9643ea8Slogwang struct callout_cpu *cc;
228a9643ea8Slogwang
229a9643ea8Slogwang /*
230a9643ea8Slogwang * Calculate the size of the callout wheel and the preallocated
231a9643ea8Slogwang * timeout() structures.
232a9643ea8Slogwang * XXX: Clip callout to result of previous function of maxusers
233a9643ea8Slogwang * maximum 384. This is still huge, but acceptable.
234a9643ea8Slogwang */
235a9643ea8Slogwang memset(CC_CPU(0), 0, sizeof(cc_cpu));
236a9643ea8Slogwang ncallout = imin(16 + maxproc + maxfiles, 18508);
237a9643ea8Slogwang TUNABLE_INT_FETCH("kern.ncallout", &ncallout);
238a9643ea8Slogwang
239a9643ea8Slogwang /*
240a9643ea8Slogwang * Calculate callout wheel size, should be next power of two higher
241a9643ea8Slogwang * than 'ncallout'.
242a9643ea8Slogwang */
243a9643ea8Slogwang callwheelsize = 1 << fls(ncallout);
244a9643ea8Slogwang callwheelmask = callwheelsize - 1;
245a9643ea8Slogwang
246a9643ea8Slogwang /*
247a9643ea8Slogwang * Fetch whether we're pinning the swi's or not.
248a9643ea8Slogwang */
249a9643ea8Slogwang TUNABLE_INT_FETCH("kern.pin_default_swi", &pin_default_swi);
250a9643ea8Slogwang TUNABLE_INT_FETCH("kern.pin_pcpu_swi", &pin_pcpu_swi);
251a9643ea8Slogwang
252a9643ea8Slogwang /*
253a9643ea8Slogwang * Only cpu0 handles timeout(9) and receives a preallocation.
254a9643ea8Slogwang *
255a9643ea8Slogwang * XXX: Once all timeout(9) consumers are converted this can
256a9643ea8Slogwang * be removed.
257a9643ea8Slogwang */
258a9643ea8Slogwang timeout_cpu = PCPU_GET(cpuid);
259a9643ea8Slogwang cc = CC_CPU(timeout_cpu);
260a9643ea8Slogwang cc->cc_callout = malloc(ncallout * sizeof(struct callout),
261a9643ea8Slogwang M_CALLOUT, M_WAITOK);
262a9643ea8Slogwang callout_cpu_init(cc, timeout_cpu);
263a9643ea8Slogwang }
264a9643ea8Slogwang SYSINIT(callwheel_init, SI_SUB_CPU, SI_ORDER_ANY, callout_callwheel_init, NULL);
265a9643ea8Slogwang
266a9643ea8Slogwang /*
267a9643ea8Slogwang * Initialize the per-cpu callout structures.
268a9643ea8Slogwang */
269a9643ea8Slogwang static void
callout_cpu_init(struct callout_cpu * cc,int cpu)270a9643ea8Slogwang callout_cpu_init(struct callout_cpu *cc, int cpu)
271a9643ea8Slogwang {
272a9643ea8Slogwang struct callout *c;
273a9643ea8Slogwang int i;
274a9643ea8Slogwang
275a9643ea8Slogwang mtx_init(&cc->cc_lock, "callout", NULL, MTX_SPIN | MTX_RECURSE);
276a9643ea8Slogwang SLIST_INIT(&cc->cc_callfree);
277a9643ea8Slogwang cc->cc_inited = 1;
278a9643ea8Slogwang cc->cc_callwheel = malloc(sizeof(struct callout_list) * callwheelsize,
279a9643ea8Slogwang M_CALLOUT, M_WAITOK);
280a9643ea8Slogwang for (i = 0; i < callwheelsize; i++)
281a9643ea8Slogwang LIST_INIT(&cc->cc_callwheel[i]);
282a9643ea8Slogwang TAILQ_INIT(&cc->cc_expireq);
283a9643ea8Slogwang for (i = 0; i < 2; i++)
284a9643ea8Slogwang cc_cce_cleanup(cc, i);
285a9643ea8Slogwang snprintf(cc->cc_ktr_event_name, sizeof(cc->cc_ktr_event_name),
286a9643ea8Slogwang "callwheel cpu %d", cpu);
287a9643ea8Slogwang if (cc->cc_callout == NULL) /* Only cpu0 handles timeout(9) */
288a9643ea8Slogwang return;
289a9643ea8Slogwang for (i = 0; i < ncallout; i++) {
290a9643ea8Slogwang c = &cc->cc_callout[i];
291a9643ea8Slogwang callout_init(c, 0);
292a9643ea8Slogwang c->c_iflags = CALLOUT_LOCAL_ALLOC;
293a9643ea8Slogwang SLIST_INSERT_HEAD(&cc->cc_callfree, c, c_links.sle);
294a9643ea8Slogwang }
295a9643ea8Slogwang }
296a9643ea8Slogwang
297a9643ea8Slogwang static inline u_int
callout_get_bucket(int to_ticks)2985e5c25c3Slogwang callout_get_bucket(int to_ticks)
299a9643ea8Slogwang {
3005e5c25c3Slogwang return (to_ticks & callwheelmask);
301a9643ea8Slogwang }
302a9643ea8Slogwang
303a9643ea8Slogwang void
callout_tick(void)3045e5c25c3Slogwang callout_tick(void)
305a9643ea8Slogwang {
306a9643ea8Slogwang struct callout_cpu *cc;
3075e5c25c3Slogwang int need_softclock;
3085e5c25c3Slogwang int bucket;
309a9643ea8Slogwang
3105e5c25c3Slogwang /*
3115e5c25c3Slogwang * Process callouts at a very low cpu priority, so we don't keep the
3125e5c25c3Slogwang * relatively high clock interrupt priority any longer than necessary.
3135e5c25c3Slogwang */
3145e5c25c3Slogwang need_softclock = 0;
315a9643ea8Slogwang cc = CC_SELF();
3165e5c25c3Slogwang mtx_lock(&cc->cc_lock);
3175e5c25c3Slogwang for (; (cc->cc_softticks - ticks) < 0; cc->cc_softticks++) {
3185e5c25c3Slogwang bucket = cc->cc_softticks & callwheelmask;
3195e5c25c3Slogwang if (!LIST_EMPTY(&cc->cc_callwheel[bucket])) {
3205e5c25c3Slogwang need_softclock = 1;
3215e5c25c3Slogwang break;
322a9643ea8Slogwang }
323a9643ea8Slogwang }
3245e5c25c3Slogwang mtx_unlock(&cc->cc_lock);
325a9643ea8Slogwang /*
326a9643ea8Slogwang * swi_sched acquires the thread lock, so we don't want to call it
327a9643ea8Slogwang * with cc_lock held; incorrect locking order.
328a9643ea8Slogwang */
3295e5c25c3Slogwang if (need_softclock)
330a9643ea8Slogwang softclock(cc);
331a9643ea8Slogwang }
332a9643ea8Slogwang
333a9643ea8Slogwang static struct callout_cpu *
callout_lock(struct callout * c)334a9643ea8Slogwang callout_lock(struct callout *c)
335a9643ea8Slogwang {
336a9643ea8Slogwang struct callout_cpu *cc;
337a9643ea8Slogwang int cpu;
338a9643ea8Slogwang
339a9643ea8Slogwang for (;;) {
340a9643ea8Slogwang cpu = c->c_cpu;
341a9643ea8Slogwang cc = CC_CPU(cpu);
342a9643ea8Slogwang CC_LOCK(cc);
343a9643ea8Slogwang if (cpu == c->c_cpu)
344a9643ea8Slogwang break;
345a9643ea8Slogwang CC_UNLOCK(cc);
346a9643ea8Slogwang }
347a9643ea8Slogwang return (cc);
348a9643ea8Slogwang }
349a9643ea8Slogwang
350a9643ea8Slogwang static void
callout_cc_add(struct callout * c,struct callout_cpu * cc,int to_ticks,void (* func)(void *),void * arg,int cpu,int flags)351a9643ea8Slogwang callout_cc_add(struct callout *c, struct callout_cpu *cc,
3525e5c25c3Slogwang int to_ticks, void (*func)(void *), void *arg, int cpu, int flags)
353a9643ea8Slogwang {
354a9643ea8Slogwang int bucket;
355a9643ea8Slogwang
356a9643ea8Slogwang CC_LOCK_ASSERT(cc);
3575e5c25c3Slogwang
358a9643ea8Slogwang c->c_arg = arg;
359a9643ea8Slogwang c->c_iflags |= CALLOUT_PENDING;
360a9643ea8Slogwang c->c_iflags &= ~CALLOUT_PROCESSED;
361a9643ea8Slogwang c->c_flags |= CALLOUT_ACTIVE;
362a9643ea8Slogwang if (flags & C_DIRECT_EXEC)
363a9643ea8Slogwang c->c_iflags |= CALLOUT_DIRECT;
364a9643ea8Slogwang c->c_func = func;
3655e5c25c3Slogwang c->c_time = ticks + to_ticks;
366a9643ea8Slogwang bucket = callout_get_bucket(c->c_time);
367a9643ea8Slogwang LIST_INSERT_HEAD(&cc->cc_callwheel[bucket], c, c_links.le);
368a9643ea8Slogwang if (cc->cc_bucket == bucket)
369a9643ea8Slogwang cc_exec_next(cc) = c;
370a9643ea8Slogwang }
371a9643ea8Slogwang
372a9643ea8Slogwang static void
callout_cc_del(struct callout * c,struct callout_cpu * cc)373a9643ea8Slogwang callout_cc_del(struct callout *c, struct callout_cpu *cc)
374a9643ea8Slogwang {
375a9643ea8Slogwang
376a9643ea8Slogwang if ((c->c_iflags & CALLOUT_LOCAL_ALLOC) == 0)
377a9643ea8Slogwang return;
378a9643ea8Slogwang c->c_func = NULL;
379a9643ea8Slogwang SLIST_INSERT_HEAD(&cc->cc_callfree, c, c_links.sle);
380a9643ea8Slogwang }
381a9643ea8Slogwang
382a9643ea8Slogwang static void
softclock_call_cc(struct callout * c,struct callout_cpu * cc,int * mpcalls,int * lockcalls,int * gcalls,int direct)383a9643ea8Slogwang softclock_call_cc(struct callout *c, struct callout_cpu *cc,
384a9643ea8Slogwang #ifdef CALLOUT_PROFILING
385a9643ea8Slogwang int *mpcalls, int *lockcalls, int *gcalls,
386a9643ea8Slogwang #endif
387a9643ea8Slogwang int direct)
388a9643ea8Slogwang {
389a9643ea8Slogwang struct rm_priotracker tracker;
390a9643ea8Slogwang void (*c_func)(void *);
391a9643ea8Slogwang void *c_arg;
392a9643ea8Slogwang struct lock_class *class;
393a9643ea8Slogwang struct lock_object *c_lock;
394a9643ea8Slogwang uintptr_t lock_status;
395a9643ea8Slogwang int c_iflags;
396a9643ea8Slogwang #if defined(DIAGNOSTIC) || defined(CALLOUT_PROFILING)
397a9643ea8Slogwang sbintime_t sbt1, sbt2;
398a9643ea8Slogwang struct timespec ts2;
399a9643ea8Slogwang static sbintime_t maxdt = 2 * SBT_1MS; /* 2 msec */
400a9643ea8Slogwang static timeout_t *lastfunc;
401a9643ea8Slogwang #endif
402a9643ea8Slogwang
403a9643ea8Slogwang KASSERT((c->c_iflags & CALLOUT_PENDING) == CALLOUT_PENDING,
404a9643ea8Slogwang ("softclock_call_cc: pend %p %x", c, c->c_iflags));
405a9643ea8Slogwang KASSERT((c->c_flags & CALLOUT_ACTIVE) == CALLOUT_ACTIVE,
406a9643ea8Slogwang ("softclock_call_cc: act %p %x", c, c->c_flags));
407a9643ea8Slogwang class = (c->c_lock != NULL) ? LOCK_CLASS(c->c_lock) : NULL;
408a9643ea8Slogwang lock_status = 0;
409a9643ea8Slogwang if (c->c_flags & CALLOUT_SHAREDLOCK) {
410a9643ea8Slogwang if (class == &lock_class_rm)
411a9643ea8Slogwang lock_status = (uintptr_t)&tracker;
412a9643ea8Slogwang else
413a9643ea8Slogwang lock_status = 1;
414a9643ea8Slogwang }
415a9643ea8Slogwang c_lock = c->c_lock;
416a9643ea8Slogwang c_func = c->c_func;
417a9643ea8Slogwang c_arg = c->c_arg;
418a9643ea8Slogwang c_iflags = c->c_iflags;
419a9643ea8Slogwang if (c->c_iflags & CALLOUT_LOCAL_ALLOC)
420a9643ea8Slogwang c->c_iflags = CALLOUT_LOCAL_ALLOC;
421a9643ea8Slogwang else
422a9643ea8Slogwang c->c_iflags &= ~CALLOUT_PENDING;
423a9643ea8Slogwang
424a9643ea8Slogwang cc_exec_curr(cc, direct) = c;
425a9643ea8Slogwang cc_exec_cancel(cc, direct) = false;
426a9643ea8Slogwang cc_exec_drain(cc, direct) = NULL;
427a9643ea8Slogwang CC_UNLOCK(cc);
428a9643ea8Slogwang if (c_lock != NULL) {
429a9643ea8Slogwang class->lc_lock(c_lock, lock_status);
430a9643ea8Slogwang /*
431a9643ea8Slogwang * The callout may have been cancelled
432a9643ea8Slogwang * while we switched locks.
433a9643ea8Slogwang */
434a9643ea8Slogwang if (cc_exec_cancel(cc, direct)) {
435a9643ea8Slogwang class->lc_unlock(c_lock);
436a9643ea8Slogwang goto skip;
437a9643ea8Slogwang }
438a9643ea8Slogwang /* The callout cannot be stopped now. */
439a9643ea8Slogwang cc_exec_cancel(cc, direct) = true;
440a9643ea8Slogwang if (c_lock == &Giant.lock_object) {
441a9643ea8Slogwang #ifdef CALLOUT_PROFILING
442a9643ea8Slogwang (*gcalls)++;
443a9643ea8Slogwang #endif
444a9643ea8Slogwang CTR3(KTR_CALLOUT, "callout giant %p func %p arg %p",
445a9643ea8Slogwang c, c_func, c_arg);
446a9643ea8Slogwang } else {
447a9643ea8Slogwang #ifdef CALLOUT_PROFILING
448a9643ea8Slogwang (*lockcalls)++;
449a9643ea8Slogwang #endif
450a9643ea8Slogwang CTR3(KTR_CALLOUT, "callout lock %p func %p arg %p",
451a9643ea8Slogwang c, c_func, c_arg);
452a9643ea8Slogwang }
453a9643ea8Slogwang } else {
454a9643ea8Slogwang #ifdef CALLOUT_PROFILING
455a9643ea8Slogwang (*mpcalls)++;
456a9643ea8Slogwang #endif
457a9643ea8Slogwang CTR3(KTR_CALLOUT, "callout %p func %p arg %p",
458a9643ea8Slogwang c, c_func, c_arg);
459a9643ea8Slogwang }
460a9643ea8Slogwang KTR_STATE3(KTR_SCHED, "callout", cc->cc_ktr_event_name, "running",
461a9643ea8Slogwang "func:%p", c_func, "arg:%p", c_arg, "direct:%d", direct);
462a9643ea8Slogwang #if defined(DIAGNOSTIC) || defined(CALLOUT_PROFILING)
463a9643ea8Slogwang sbt1 = sbinuptime();
464a9643ea8Slogwang #endif
465a9643ea8Slogwang THREAD_NO_SLEEPING();
466a9643ea8Slogwang SDT_PROBE1(callout_execute, , , callout__start, c);
467a9643ea8Slogwang c_func(c_arg);
468a9643ea8Slogwang SDT_PROBE1(callout_execute, , , callout__end, c);
469a9643ea8Slogwang THREAD_SLEEPING_OK();
470a9643ea8Slogwang #if defined(DIAGNOSTIC) || defined(CALLOUT_PROFILING)
471a9643ea8Slogwang sbt2 = sbinuptime();
472a9643ea8Slogwang sbt2 -= sbt1;
473a9643ea8Slogwang if (sbt2 > maxdt) {
474a9643ea8Slogwang if (lastfunc != c_func || sbt2 > maxdt * 2) {
475a9643ea8Slogwang ts2 = sbttots(sbt2);
476a9643ea8Slogwang printf(
477a9643ea8Slogwang "Expensive timeout(9) function: %p(%p) %jd.%09ld s\n",
478a9643ea8Slogwang c_func, c_arg, (intmax_t)ts2.tv_sec, ts2.tv_nsec);
479a9643ea8Slogwang }
480a9643ea8Slogwang maxdt = sbt2;
481a9643ea8Slogwang lastfunc = c_func;
482a9643ea8Slogwang }
483a9643ea8Slogwang #endif
484a9643ea8Slogwang KTR_STATE0(KTR_SCHED, "callout", cc->cc_ktr_event_name, "idle");
485a9643ea8Slogwang CTR1(KTR_CALLOUT, "callout %p finished", c);
486a9643ea8Slogwang if ((c_iflags & CALLOUT_RETURNUNLOCKED) == 0)
487a9643ea8Slogwang class->lc_unlock(c_lock);
488a9643ea8Slogwang skip:
489a9643ea8Slogwang CC_LOCK(cc);
490a9643ea8Slogwang KASSERT(cc_exec_curr(cc, direct) == c, ("mishandled cc_curr"));
491a9643ea8Slogwang cc_exec_curr(cc, direct) = NULL;
492a9643ea8Slogwang if (cc_exec_drain(cc, direct)) {
493a9643ea8Slogwang void (*drain)(void *);
494a9643ea8Slogwang
495a9643ea8Slogwang drain = cc_exec_drain(cc, direct);
496a9643ea8Slogwang cc_exec_drain(cc, direct) = NULL;
497a9643ea8Slogwang CC_UNLOCK(cc);
498a9643ea8Slogwang drain(c_arg);
499a9643ea8Slogwang CC_LOCK(cc);
500a9643ea8Slogwang }
501a9643ea8Slogwang if (cc_exec_waiting(cc, direct)) {
502a9643ea8Slogwang /*
503a9643ea8Slogwang * There is someone waiting for the
504a9643ea8Slogwang * callout to complete.
505a9643ea8Slogwang * If the callout was scheduled for
506a9643ea8Slogwang * migration just cancel it.
507a9643ea8Slogwang */
508a9643ea8Slogwang if (cc_cce_migrating(cc, direct)) {
509a9643ea8Slogwang cc_cce_cleanup(cc, direct);
510a9643ea8Slogwang
511a9643ea8Slogwang /*
512a9643ea8Slogwang * It should be assert here that the callout is not
513a9643ea8Slogwang * destroyed but that is not easy.
514a9643ea8Slogwang */
515a9643ea8Slogwang c->c_iflags &= ~CALLOUT_DFRMIGRATION;
516a9643ea8Slogwang }
517a9643ea8Slogwang cc_exec_waiting(cc, direct) = false;
518a9643ea8Slogwang CC_UNLOCK(cc);
519a9643ea8Slogwang wakeup(&cc_exec_waiting(cc, direct));
520a9643ea8Slogwang CC_LOCK(cc);
521a9643ea8Slogwang } else if (cc_cce_migrating(cc, direct)) {
522a9643ea8Slogwang KASSERT((c_iflags & CALLOUT_LOCAL_ALLOC) == 0,
523a9643ea8Slogwang ("Migrating legacy callout %p", c));
524a9643ea8Slogwang panic("migration should not happen");
525a9643ea8Slogwang }
526a9643ea8Slogwang /*
527a9643ea8Slogwang * If the current callout is locally allocated (from
528a9643ea8Slogwang * timeout(9)) then put it on the freelist.
529a9643ea8Slogwang *
530a9643ea8Slogwang * Note: we need to check the cached copy of c_iflags because
531a9643ea8Slogwang * if it was not local, then it's not safe to deref the
532a9643ea8Slogwang * callout pointer.
533a9643ea8Slogwang */
534a9643ea8Slogwang KASSERT((c_iflags & CALLOUT_LOCAL_ALLOC) == 0 ||
535a9643ea8Slogwang c->c_iflags == CALLOUT_LOCAL_ALLOC,
536a9643ea8Slogwang ("corrupted callout"));
537a9643ea8Slogwang if (c_iflags & CALLOUT_LOCAL_ALLOC)
538a9643ea8Slogwang callout_cc_del(c, cc);
539a9643ea8Slogwang }
540a9643ea8Slogwang
541a9643ea8Slogwang /*
542a9643ea8Slogwang * The callout mechanism is based on the work of Adam M. Costello and
543a9643ea8Slogwang * George Varghese, published in a technical report entitled "Redesigning
544a9643ea8Slogwang * the BSD Callout and Timer Facilities" and modified slightly for inclusion
545a9643ea8Slogwang * in FreeBSD by Justin T. Gibbs. The original work on the data structures
546a9643ea8Slogwang * used in this implementation was published by G. Varghese and T. Lauck in
547a9643ea8Slogwang * the paper "Hashed and Hierarchical Timing Wheels: Data Structures for
548a9643ea8Slogwang * the Efficient Implementation of a Timer Facility" in the Proceedings of
549a9643ea8Slogwang * the 11th ACM Annual Symposium on Operating Systems Principles,
550a9643ea8Slogwang * Austin, Texas Nov 1987.
551a9643ea8Slogwang */
552a9643ea8Slogwang
553a9643ea8Slogwang /*
554a9643ea8Slogwang * Software (low priority) clock interrupt.
555a9643ea8Slogwang * Run periodic events from timeout queue.
556a9643ea8Slogwang */
557a9643ea8Slogwang void
softclock(void * arg)558a9643ea8Slogwang softclock(void *arg)
559a9643ea8Slogwang {
560a9643ea8Slogwang struct callout *c;
5615e5c25c3Slogwang struct callout_cpu *cc;
5625e5c25c3Slogwang struct callout_list *sc;
5635e5c25c3Slogwang int curticks;
564a9643ea8Slogwang #ifdef CALLOUT_PROFILING
5655e5c25c3Slogwang int depth = 0, gcalls = 0, mpcalls = 0, lockcalls = 0;
566a9643ea8Slogwang #endif
567a9643ea8Slogwang
568a9643ea8Slogwang cc = (struct callout_cpu *)arg;
569a9643ea8Slogwang CC_LOCK(cc);
5705e5c25c3Slogwang
5715e5c25c3Slogwang while (cc->cc_softticks != ticks) {
5725e5c25c3Slogwang /*
5735e5c25c3Slogwang * cc_softticks may be modified by hard clock, so cache
5745e5c25c3Slogwang * it while we work on a given bucket.
5755e5c25c3Slogwang */
5765e5c25c3Slogwang curticks = cc->cc_softticks;
5775e5c25c3Slogwang cc->cc_softticks++;
5785e5c25c3Slogwang sc = &cc->cc_callwheel[curticks & callwheelmask];
5795e5c25c3Slogwang c = LIST_FIRST(sc);
5805e5c25c3Slogwang while (c) {
5815e5c25c3Slogwang #ifdef CALLOUT_PROFILING
5825e5c25c3Slogwang depth++;
5835e5c25c3Slogwang #endif
5845e5c25c3Slogwang if (c->c_time != curticks) {
5855e5c25c3Slogwang c = LIST_NEXT(c, c_links.le);
5865e5c25c3Slogwang } else {
5875e5c25c3Slogwang cc_exec_next(cc) =
5885e5c25c3Slogwang LIST_NEXT(c, c_links.le);
5895e5c25c3Slogwang cc->cc_bucket = callout_get_bucket(curticks);
5905e5c25c3Slogwang LIST_REMOVE(c, c_links.le);
591a9643ea8Slogwang softclock_call_cc(c, cc,
592a9643ea8Slogwang #ifdef CALLOUT_PROFILING
593a9643ea8Slogwang &mpcalls, &lockcalls, &gcalls,
594a9643ea8Slogwang #endif
5955e5c25c3Slogwang 1);
5965e5c25c3Slogwang c = cc_exec_next(cc);
5975e5c25c3Slogwang cc_exec_next(cc) = NULL;
598a9643ea8Slogwang }
5995e5c25c3Slogwang }
6005e5c25c3Slogwang }
6015e5c25c3Slogwang
602a9643ea8Slogwang #ifdef CALLOUT_PROFILING
603a9643ea8Slogwang avg_depth += (depth * 1000 - avg_depth) >> 8;
604a9643ea8Slogwang avg_mpcalls += (mpcalls * 1000 - avg_mpcalls) >> 8;
605a9643ea8Slogwang avg_lockcalls += (lockcalls * 1000 - avg_lockcalls) >> 8;
606a9643ea8Slogwang avg_gcalls += (gcalls * 1000 - avg_gcalls) >> 8;
607a9643ea8Slogwang #endif
608a9643ea8Slogwang CC_UNLOCK(cc);
609a9643ea8Slogwang }
610a9643ea8Slogwang
61122ce4affSfengbojiang #if 0
612a9643ea8Slogwang /*
613a9643ea8Slogwang * timeout --
614a9643ea8Slogwang * Execute a function after a specified length of time.
615a9643ea8Slogwang *
616a9643ea8Slogwang * untimeout --
617a9643ea8Slogwang * Cancel previous timeout function call.
618a9643ea8Slogwang *
619a9643ea8Slogwang * callout_handle_init --
620a9643ea8Slogwang * Initialize a handle so that using it with untimeout is benign.
621a9643ea8Slogwang *
622a9643ea8Slogwang * See AT&T BCI Driver Reference Manual for specification. This
623a9643ea8Slogwang * implementation differs from that one in that although an
624a9643ea8Slogwang * identification value is returned from timeout, the original
625a9643ea8Slogwang * arguments to timeout as well as the identifier are used to
626a9643ea8Slogwang * identify entries for untimeout.
627a9643ea8Slogwang */
628a9643ea8Slogwang struct callout_handle
629a9643ea8Slogwang timeout(timeout_t *ftn, void *arg, int to_ticks)
630a9643ea8Slogwang {
631a9643ea8Slogwang struct callout_cpu *cc;
632a9643ea8Slogwang struct callout *new;
633a9643ea8Slogwang struct callout_handle handle;
634a9643ea8Slogwang
635a9643ea8Slogwang cc = CC_CPU(timeout_cpu);
636a9643ea8Slogwang CC_LOCK(cc);
637a9643ea8Slogwang /* Fill in the next free callout structure. */
638a9643ea8Slogwang new = SLIST_FIRST(&cc->cc_callfree);
639a9643ea8Slogwang if (new == NULL)
640a9643ea8Slogwang /* XXX Attempt to malloc first */
641a9643ea8Slogwang panic("timeout table full");
642a9643ea8Slogwang SLIST_REMOVE_HEAD(&cc->cc_callfree, c_links.sle);
643a9643ea8Slogwang callout_reset(new, to_ticks, ftn, arg);
644a9643ea8Slogwang handle.callout = new;
645a9643ea8Slogwang CC_UNLOCK(cc);
646a9643ea8Slogwang
647a9643ea8Slogwang return (handle);
648a9643ea8Slogwang }
649a9643ea8Slogwang
650a9643ea8Slogwang void
651a9643ea8Slogwang untimeout(timeout_t *ftn, void *arg, struct callout_handle handle)
652a9643ea8Slogwang {
653a9643ea8Slogwang struct callout_cpu *cc;
654a9643ea8Slogwang
655a9643ea8Slogwang /*
656a9643ea8Slogwang * Check for a handle that was initialized
657a9643ea8Slogwang * by callout_handle_init, but never used
658a9643ea8Slogwang * for a real timeout.
659a9643ea8Slogwang */
660a9643ea8Slogwang if (handle.callout == NULL)
661a9643ea8Slogwang return;
662a9643ea8Slogwang
663a9643ea8Slogwang cc = callout_lock(handle.callout);
664a9643ea8Slogwang if (handle.callout->c_func == ftn && handle.callout->c_arg == arg)
665a9643ea8Slogwang callout_stop(handle.callout);
666a9643ea8Slogwang CC_UNLOCK(cc);
667a9643ea8Slogwang }
668a9643ea8Slogwang
669a9643ea8Slogwang void
670a9643ea8Slogwang callout_handle_init(struct callout_handle *handle)
671a9643ea8Slogwang {
672a9643ea8Slogwang handle->callout = NULL;
673a9643ea8Slogwang }
67422ce4affSfengbojiang #endif
675a9643ea8Slogwang
676a9643ea8Slogwang /*
677a9643ea8Slogwang * New interface; clients allocate their own callout structures.
678a9643ea8Slogwang *
679a9643ea8Slogwang * callout_reset() - establish or change a timeout
680a9643ea8Slogwang * callout_stop() - disestablish a timeout
681a9643ea8Slogwang * callout_init() - initialize a callout structure so that it can
682a9643ea8Slogwang * safely be passed to callout_reset() and callout_stop()
683a9643ea8Slogwang *
684a9643ea8Slogwang * <sys/callout.h> defines three convenience macros:
685a9643ea8Slogwang *
686a9643ea8Slogwang * callout_active() - returns truth if callout has not been stopped,
687a9643ea8Slogwang * drained, or deactivated since the last time the callout was
688a9643ea8Slogwang * reset.
689a9643ea8Slogwang * callout_pending() - returns truth if callout is still waiting for timeout
690a9643ea8Slogwang * callout_deactivate() - marks the callout as having been serviced
691a9643ea8Slogwang */
692a9643ea8Slogwang int
callout_reset_tick_on(struct callout * c,int to_ticks,void (* ftn)(void *),void * arg,int cpu,int flags)6935e5c25c3Slogwang callout_reset_tick_on(struct callout *c, int to_ticks,
694a9643ea8Slogwang void (*ftn)(void *), void *arg, int cpu, int flags)
695a9643ea8Slogwang {
696a9643ea8Slogwang struct callout_cpu *cc;
697a9643ea8Slogwang int cancelled, direct;
698a9643ea8Slogwang int ignore_cpu=0;
699a9643ea8Slogwang
700a9643ea8Slogwang cancelled = 0;
701a9643ea8Slogwang if (cpu == -1) {
702a9643ea8Slogwang ignore_cpu = 1;
703a9643ea8Slogwang } else if ((cpu >= MAXCPU) ||
704a9643ea8Slogwang ((CC_CPU(cpu))->cc_inited == 0)) {
705a9643ea8Slogwang /* Invalid CPU spec */
706a9643ea8Slogwang panic("Invalid CPU in callout %d", cpu);
707a9643ea8Slogwang }
708a9643ea8Slogwang
709a9643ea8Slogwang /*
710a9643ea8Slogwang * This flag used to be added by callout_cc_add, but the
711a9643ea8Slogwang * first time you call this we could end up with the
712a9643ea8Slogwang * wrong direct flag if we don't do it before we add.
713a9643ea8Slogwang */
714a9643ea8Slogwang if (flags & C_DIRECT_EXEC) {
715a9643ea8Slogwang direct = 1;
716a9643ea8Slogwang } else {
717a9643ea8Slogwang direct = 0;
718a9643ea8Slogwang }
719a9643ea8Slogwang KASSERT(!direct || c->c_lock == NULL,
720a9643ea8Slogwang ("%s: direct callout %p has lock", __func__, c));
721a9643ea8Slogwang cc = callout_lock(c);
722a9643ea8Slogwang /*
723a9643ea8Slogwang * Don't allow migration of pre-allocated callouts lest they
724a9643ea8Slogwang * become unbalanced or handle the case where the user does
725a9643ea8Slogwang * not care.
726a9643ea8Slogwang */
727a9643ea8Slogwang if ((c->c_iflags & CALLOUT_LOCAL_ALLOC) ||
728a9643ea8Slogwang ignore_cpu) {
729a9643ea8Slogwang cpu = c->c_cpu;
730a9643ea8Slogwang }
731a9643ea8Slogwang
732a9643ea8Slogwang if (cc_exec_curr(cc, direct) == c) {
733a9643ea8Slogwang /*
734a9643ea8Slogwang * We're being asked to reschedule a callout which is
735a9643ea8Slogwang * currently in progress. If there is a lock then we
736a9643ea8Slogwang * can cancel the callout if it has not really started.
737a9643ea8Slogwang */
738a9643ea8Slogwang if (c->c_lock != NULL && !cc_exec_cancel(cc, direct))
739a9643ea8Slogwang cancelled = cc_exec_cancel(cc, direct) = true;
740a9643ea8Slogwang if (cc_exec_waiting(cc, direct)) {
741a9643ea8Slogwang /*
742a9643ea8Slogwang * Someone has called callout_drain to kill this
743a9643ea8Slogwang * callout. Don't reschedule.
744a9643ea8Slogwang */
745a9643ea8Slogwang CTR4(KTR_CALLOUT, "%s %p func %p arg %p",
746a9643ea8Slogwang cancelled ? "cancelled" : "failed to cancel",
747a9643ea8Slogwang c, c->c_func, c->c_arg);
748a9643ea8Slogwang CC_UNLOCK(cc);
749a9643ea8Slogwang return (cancelled);
750a9643ea8Slogwang }
751a9643ea8Slogwang }
752a9643ea8Slogwang if (c->c_iflags & CALLOUT_PENDING) {
753a9643ea8Slogwang if ((c->c_iflags & CALLOUT_PROCESSED) == 0) {
754a9643ea8Slogwang if (cc_exec_next(cc) == c)
755a9643ea8Slogwang cc_exec_next(cc) = LIST_NEXT(c, c_links.le);
756a9643ea8Slogwang LIST_REMOVE(c, c_links.le);
757a9643ea8Slogwang } else {
758a9643ea8Slogwang TAILQ_REMOVE(&cc->cc_expireq, c, c_links.tqe);
759a9643ea8Slogwang }
760a9643ea8Slogwang cancelled = 1;
761a9643ea8Slogwang c->c_iflags &= ~ CALLOUT_PENDING;
762a9643ea8Slogwang c->c_flags &= ~ CALLOUT_ACTIVE;
763a9643ea8Slogwang }
764a9643ea8Slogwang
7655e5c25c3Slogwang if (to_ticks <= 0)
7665e5c25c3Slogwang to_ticks = 1;
767a9643ea8Slogwang
7685e5c25c3Slogwang callout_cc_add(c, cc, to_ticks, ftn, arg, cpu, flags);
7695e5c25c3Slogwang CTR5(KTR_CALLOUT, "%sscheduled %p func %p arg %p in %d",
7705e5c25c3Slogwang cancelled ? "re" : "", c, c->c_func, c->c_arg, to_ticks);
771a9643ea8Slogwang CC_UNLOCK(cc);
772a9643ea8Slogwang
773a9643ea8Slogwang return (cancelled);
774a9643ea8Slogwang }
775a9643ea8Slogwang
776a9643ea8Slogwang /*
777a9643ea8Slogwang * Common idioms that can be optimized in the future.
778a9643ea8Slogwang */
779a9643ea8Slogwang int
callout_schedule_on(struct callout * c,int to_ticks,int cpu)780a9643ea8Slogwang callout_schedule_on(struct callout *c, int to_ticks, int cpu)
781a9643ea8Slogwang {
782a9643ea8Slogwang return callout_reset_on(c, to_ticks, c->c_func, c->c_arg, cpu);
783a9643ea8Slogwang }
784a9643ea8Slogwang
785a9643ea8Slogwang int
callout_schedule(struct callout * c,int to_ticks)786a9643ea8Slogwang callout_schedule(struct callout *c, int to_ticks)
787a9643ea8Slogwang {
788a9643ea8Slogwang return callout_reset_on(c, to_ticks, c->c_func, c->c_arg, c->c_cpu);
789a9643ea8Slogwang }
790a9643ea8Slogwang
791a9643ea8Slogwang int
_callout_stop_safe(struct callout * c,int flags,void (* drain)(void *))792a9643ea8Slogwang _callout_stop_safe(struct callout *c, int flags, void (*drain)(void *))
793a9643ea8Slogwang {
794a9643ea8Slogwang struct callout_cpu *cc, *old_cc;
795a9643ea8Slogwang struct lock_class *class;
796a9643ea8Slogwang int direct, sq_locked, use_lock;
797a9643ea8Slogwang int cancelled, not_on_a_list;
798a9643ea8Slogwang
799a9643ea8Slogwang if ((flags & CS_DRAIN) != 0)
800a9643ea8Slogwang WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, c->c_lock,
801a9643ea8Slogwang "calling %s", __func__);
802a9643ea8Slogwang
803a9643ea8Slogwang /*
804a9643ea8Slogwang * Some old subsystems don't hold Giant while running a callout_stop(),
805a9643ea8Slogwang * so just discard this check for the moment.
806a9643ea8Slogwang */
807a9643ea8Slogwang if ((flags & CS_DRAIN) == 0 && c->c_lock != NULL) {
808a9643ea8Slogwang if (c->c_lock == &Giant.lock_object)
809a9643ea8Slogwang use_lock = mtx_owned(&Giant);
810a9643ea8Slogwang else {
811a9643ea8Slogwang use_lock = 1;
812a9643ea8Slogwang class = LOCK_CLASS(c->c_lock);
813a9643ea8Slogwang class->lc_assert(c->c_lock, LA_XLOCKED);
814a9643ea8Slogwang }
815a9643ea8Slogwang } else
816a9643ea8Slogwang use_lock = 0;
817a9643ea8Slogwang if (c->c_iflags & CALLOUT_DIRECT) {
818a9643ea8Slogwang direct = 1;
819a9643ea8Slogwang } else {
820a9643ea8Slogwang direct = 0;
821a9643ea8Slogwang }
822a9643ea8Slogwang sq_locked = 0;
823a9643ea8Slogwang old_cc = NULL;
824a9643ea8Slogwang again:
825a9643ea8Slogwang cc = callout_lock(c);
826a9643ea8Slogwang
827a9643ea8Slogwang if ((c->c_iflags & (CALLOUT_DFRMIGRATION | CALLOUT_PENDING)) ==
828a9643ea8Slogwang (CALLOUT_DFRMIGRATION | CALLOUT_PENDING) &&
829a9643ea8Slogwang ((c->c_flags & CALLOUT_ACTIVE) == CALLOUT_ACTIVE)) {
830a9643ea8Slogwang /*
831a9643ea8Slogwang * Special case where this slipped in while we
832a9643ea8Slogwang * were migrating *as* the callout is about to
833a9643ea8Slogwang * execute. The caller probably holds the lock
834a9643ea8Slogwang * the callout wants.
835a9643ea8Slogwang *
836a9643ea8Slogwang * Get rid of the migration first. Then set
837a9643ea8Slogwang * the flag that tells this code *not* to
838a9643ea8Slogwang * try to remove it from any lists (its not
839a9643ea8Slogwang * on one yet). When the callout wheel runs,
840a9643ea8Slogwang * it will ignore this callout.
841a9643ea8Slogwang */
842a9643ea8Slogwang c->c_iflags &= ~CALLOUT_PENDING;
843a9643ea8Slogwang c->c_flags &= ~CALLOUT_ACTIVE;
844a9643ea8Slogwang not_on_a_list = 1;
845a9643ea8Slogwang } else {
846a9643ea8Slogwang not_on_a_list = 0;
847a9643ea8Slogwang }
848a9643ea8Slogwang
849a9643ea8Slogwang /*
850a9643ea8Slogwang * If the callout was migrating while the callout cpu lock was
851a9643ea8Slogwang * dropped, just drop the sleepqueue lock and check the states
852a9643ea8Slogwang * again.
853a9643ea8Slogwang */
854a9643ea8Slogwang if (sq_locked != 0 && cc != old_cc) {
855a9643ea8Slogwang panic("migration should not happen");
856a9643ea8Slogwang }
857a9643ea8Slogwang
858a9643ea8Slogwang /*
859a9643ea8Slogwang * If the callout is running, try to stop it or drain it.
860a9643ea8Slogwang */
861a9643ea8Slogwang if (cc_exec_curr(cc, direct) == c) {
862a9643ea8Slogwang /*
863a9643ea8Slogwang * Succeed we to stop it or not, we must clear the
864a9643ea8Slogwang * active flag - this is what API users expect.
865a9643ea8Slogwang */
866a9643ea8Slogwang c->c_flags &= ~CALLOUT_ACTIVE;
867a9643ea8Slogwang
868a9643ea8Slogwang if ((flags & CS_DRAIN) != 0) {
869a9643ea8Slogwang /*
870a9643ea8Slogwang * The current callout is running (or just
871a9643ea8Slogwang * about to run) and blocking is allowed, so
872a9643ea8Slogwang * just wait for the current invocation to
873a9643ea8Slogwang * finish.
874a9643ea8Slogwang */
875a9643ea8Slogwang while (cc_exec_curr(cc, direct) == c) {
876a9643ea8Slogwang /*
877a9643ea8Slogwang * Use direct calls to sleepqueue interface
878a9643ea8Slogwang * instead of cv/msleep in order to avoid
879a9643ea8Slogwang * a LOR between cc_lock and sleepqueue
880a9643ea8Slogwang * chain spinlocks. This piece of code
881a9643ea8Slogwang * emulates a msleep_spin() call actually.
882a9643ea8Slogwang *
883a9643ea8Slogwang * If we already have the sleepqueue chain
884a9643ea8Slogwang * locked, then we can safely block. If we
885a9643ea8Slogwang * don't already have it locked, however,
886a9643ea8Slogwang * we have to drop the cc_lock to lock
887a9643ea8Slogwang * it. This opens several races, so we
888a9643ea8Slogwang * restart at the beginning once we have
889a9643ea8Slogwang * both locks. If nothing has changed, then
890a9643ea8Slogwang * we will end up back here with sq_locked
891a9643ea8Slogwang * set.
892a9643ea8Slogwang */
893a9643ea8Slogwang if (!sq_locked) {
894a9643ea8Slogwang CC_UNLOCK(cc);
895a9643ea8Slogwang sleepq_lock(
896a9643ea8Slogwang &cc_exec_waiting(cc, direct));
897a9643ea8Slogwang sq_locked = 1;
898a9643ea8Slogwang old_cc = cc;
899a9643ea8Slogwang goto again;
900a9643ea8Slogwang }
901a9643ea8Slogwang
902a9643ea8Slogwang /*
903a9643ea8Slogwang * Migration could be cancelled here, but
904a9643ea8Slogwang * as long as it is still not sure when it
905a9643ea8Slogwang * will be packed up, just let softclock()
906a9643ea8Slogwang * take care of it.
907a9643ea8Slogwang */
908a9643ea8Slogwang cc_exec_waiting(cc, direct) = true;
909a9643ea8Slogwang DROP_GIANT();
910a9643ea8Slogwang CC_UNLOCK(cc);
911a9643ea8Slogwang sleepq_add(
912a9643ea8Slogwang &cc_exec_waiting(cc, direct),
913a9643ea8Slogwang &cc->cc_lock.lock_object, "codrain",
914a9643ea8Slogwang SLEEPQ_SLEEP, 0);
915a9643ea8Slogwang sleepq_wait(
916a9643ea8Slogwang &cc_exec_waiting(cc, direct),
917a9643ea8Slogwang 0);
918a9643ea8Slogwang sq_locked = 0;
919a9643ea8Slogwang old_cc = NULL;
920a9643ea8Slogwang
921a9643ea8Slogwang /* Reacquire locks previously released. */
922a9643ea8Slogwang PICKUP_GIANT();
923a9643ea8Slogwang CC_LOCK(cc);
924a9643ea8Slogwang }
925a9643ea8Slogwang } else if (use_lock &&
926a9643ea8Slogwang !cc_exec_cancel(cc, direct) && (drain == NULL)) {
927a9643ea8Slogwang
928a9643ea8Slogwang /*
929a9643ea8Slogwang * The current callout is waiting for its
930a9643ea8Slogwang * lock which we hold. Cancel the callout
931a9643ea8Slogwang * and return. After our caller drops the
932a9643ea8Slogwang * lock, the callout will be skipped in
933a9643ea8Slogwang * softclock(). This *only* works with a
934a9643ea8Slogwang * callout_stop() *not* callout_drain() or
935a9643ea8Slogwang * callout_async_drain().
936a9643ea8Slogwang */
937a9643ea8Slogwang cc_exec_cancel(cc, direct) = true;
938a9643ea8Slogwang CTR3(KTR_CALLOUT, "cancelled %p func %p arg %p",
939a9643ea8Slogwang c, c->c_func, c->c_arg);
940a9643ea8Slogwang KASSERT(!cc_cce_migrating(cc, direct),
941a9643ea8Slogwang ("callout wrongly scheduled for migration"));
942a9643ea8Slogwang if (callout_migrating(c)) {
943a9643ea8Slogwang c->c_iflags &= ~CALLOUT_DFRMIGRATION;
944a9643ea8Slogwang }
945a9643ea8Slogwang CC_UNLOCK(cc);
946a9643ea8Slogwang KASSERT(!sq_locked, ("sleepqueue chain locked"));
947a9643ea8Slogwang return (1);
948a9643ea8Slogwang } else if (callout_migrating(c)) {
949a9643ea8Slogwang /*
950a9643ea8Slogwang * The callout is currently being serviced
951a9643ea8Slogwang * and the "next" callout is scheduled at
952a9643ea8Slogwang * its completion with a migration. We remove
953a9643ea8Slogwang * the migration flag so it *won't* get rescheduled,
954a9643ea8Slogwang * but we can't stop the one thats running so
955a9643ea8Slogwang * we return 0.
956a9643ea8Slogwang */
957a9643ea8Slogwang c->c_iflags &= ~CALLOUT_DFRMIGRATION;
958a9643ea8Slogwang CTR3(KTR_CALLOUT, "postponing stop %p func %p arg %p",
959a9643ea8Slogwang c, c->c_func, c->c_arg);
960a9643ea8Slogwang if (drain) {
961a9643ea8Slogwang cc_exec_drain(cc, direct) = drain;
962a9643ea8Slogwang }
963a9643ea8Slogwang CC_UNLOCK(cc);
964a9643ea8Slogwang return ((flags & CS_EXECUTING) != 0);
965a9643ea8Slogwang }
966a9643ea8Slogwang CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p",
967a9643ea8Slogwang c, c->c_func, c->c_arg);
968a9643ea8Slogwang if (drain) {
969a9643ea8Slogwang cc_exec_drain(cc, direct) = drain;
970a9643ea8Slogwang }
971a9643ea8Slogwang KASSERT(!sq_locked, ("sleepqueue chain still locked"));
972a9643ea8Slogwang cancelled = ((flags & CS_EXECUTING) != 0);
973a9643ea8Slogwang } else
974a9643ea8Slogwang cancelled = 1;
975a9643ea8Slogwang
976a9643ea8Slogwang if (sq_locked)
977a9643ea8Slogwang sleepq_release(&cc_exec_waiting(cc, direct));
978a9643ea8Slogwang
979a9643ea8Slogwang if ((c->c_iflags & CALLOUT_PENDING) == 0) {
980a9643ea8Slogwang CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p",
981a9643ea8Slogwang c, c->c_func, c->c_arg);
982a9643ea8Slogwang /*
983a9643ea8Slogwang * For not scheduled and not executing callout return
984a9643ea8Slogwang * negative value.
985a9643ea8Slogwang */
986a9643ea8Slogwang if (cc_exec_curr(cc, direct) != c)
987a9643ea8Slogwang cancelled = -1;
988a9643ea8Slogwang CC_UNLOCK(cc);
989a9643ea8Slogwang return (cancelled);
990a9643ea8Slogwang }
991a9643ea8Slogwang
992a9643ea8Slogwang c->c_iflags &= ~CALLOUT_PENDING;
993a9643ea8Slogwang c->c_flags &= ~CALLOUT_ACTIVE;
994a9643ea8Slogwang
995a9643ea8Slogwang CTR3(KTR_CALLOUT, "cancelled %p func %p arg %p",
996a9643ea8Slogwang c, c->c_func, c->c_arg);
997a9643ea8Slogwang if (not_on_a_list == 0) {
998a9643ea8Slogwang if ((c->c_iflags & CALLOUT_PROCESSED) == 0) {
999a9643ea8Slogwang if (cc_exec_next(cc) == c)
1000a9643ea8Slogwang cc_exec_next(cc) = LIST_NEXT(c, c_links.le);
1001a9643ea8Slogwang LIST_REMOVE(c, c_links.le);
1002a9643ea8Slogwang } else {
1003a9643ea8Slogwang TAILQ_REMOVE(&cc->cc_expireq, c, c_links.tqe);
1004a9643ea8Slogwang }
1005a9643ea8Slogwang }
1006a9643ea8Slogwang callout_cc_del(c, cc);
1007a9643ea8Slogwang CC_UNLOCK(cc);
1008a9643ea8Slogwang return (cancelled);
1009a9643ea8Slogwang }
1010a9643ea8Slogwang
1011a9643ea8Slogwang void
callout_init(struct callout * c,int mpsafe)1012a9643ea8Slogwang callout_init(struct callout *c, int mpsafe)
1013a9643ea8Slogwang {
1014a9643ea8Slogwang bzero(c, sizeof *c);
1015a9643ea8Slogwang if (mpsafe) {
1016a9643ea8Slogwang c->c_lock = NULL;
1017a9643ea8Slogwang c->c_iflags = CALLOUT_RETURNUNLOCKED;
1018a9643ea8Slogwang } else {
1019a9643ea8Slogwang c->c_lock = &Giant.lock_object;
1020a9643ea8Slogwang c->c_iflags = 0;
1021a9643ea8Slogwang }
1022a9643ea8Slogwang c->c_cpu = timeout_cpu;
1023a9643ea8Slogwang }
1024a9643ea8Slogwang
1025a9643ea8Slogwang void
_callout_init_lock(struct callout * c,struct lock_object * lock,int flags)1026a9643ea8Slogwang _callout_init_lock(struct callout *c, struct lock_object *lock, int flags)
1027a9643ea8Slogwang {
1028a9643ea8Slogwang bzero(c, sizeof *c);
1029a9643ea8Slogwang c->c_lock = lock;
1030a9643ea8Slogwang KASSERT((flags & ~(CALLOUT_RETURNUNLOCKED | CALLOUT_SHAREDLOCK)) == 0,
1031a9643ea8Slogwang ("callout_init_lock: bad flags %d", flags));
1032a9643ea8Slogwang KASSERT(lock != NULL || (flags & CALLOUT_RETURNUNLOCKED) == 0,
1033a9643ea8Slogwang ("callout_init_lock: CALLOUT_RETURNUNLOCKED with no lock"));
1034a9643ea8Slogwang KASSERT(lock == NULL || !(LOCK_CLASS(lock)->lc_flags &
1035a9643ea8Slogwang (LC_SPINLOCK | LC_SLEEPABLE)), ("%s: invalid lock class",
1036a9643ea8Slogwang __func__));
1037a9643ea8Slogwang c->c_iflags = flags & (CALLOUT_RETURNUNLOCKED | CALLOUT_SHAREDLOCK);
1038a9643ea8Slogwang c->c_cpu = timeout_cpu;
1039a9643ea8Slogwang }
1040a9643ea8Slogwang
1041a9643ea8Slogwang #ifdef APM_FIXUP_CALLTODO
1042a9643ea8Slogwang /*
1043a9643ea8Slogwang * Adjust the kernel calltodo timeout list. This routine is used after
1044a9643ea8Slogwang * an APM resume to recalculate the calltodo timer list values with the
1045a9643ea8Slogwang * number of hz's we have been sleeping. The next hardclock() will detect
1046a9643ea8Slogwang * that there are fired timers and run softclock() to execute them.
1047a9643ea8Slogwang *
1048a9643ea8Slogwang * Please note, I have not done an exhaustive analysis of what code this
1049a9643ea8Slogwang * might break. I am motivated to have my select()'s and alarm()'s that
1050a9643ea8Slogwang * have expired during suspend firing upon resume so that the applications
1051a9643ea8Slogwang * which set the timer can do the maintanence the timer was for as close
1052a9643ea8Slogwang * as possible to the originally intended time. Testing this code for a
1053a9643ea8Slogwang * week showed that resuming from a suspend resulted in 22 to 25 timers
1054a9643ea8Slogwang * firing, which seemed independent on whether the suspend was 2 hours or
1055a9643ea8Slogwang * 2 days. Your milage may vary. - Ken Key <[email protected]>
1056a9643ea8Slogwang */
1057a9643ea8Slogwang void
adjust_timeout_calltodo(struct timeval * time_change)1058a9643ea8Slogwang adjust_timeout_calltodo(struct timeval *time_change)
1059a9643ea8Slogwang {
1060a9643ea8Slogwang register struct callout *p;
1061a9643ea8Slogwang unsigned long delta_ticks;
1062a9643ea8Slogwang
1063a9643ea8Slogwang /*
1064a9643ea8Slogwang * How many ticks were we asleep?
1065a9643ea8Slogwang * (stolen from tvtohz()).
1066a9643ea8Slogwang */
1067a9643ea8Slogwang
1068a9643ea8Slogwang /* Don't do anything */
1069a9643ea8Slogwang if (time_change->tv_sec < 0)
1070a9643ea8Slogwang return;
1071a9643ea8Slogwang else if (time_change->tv_sec <= LONG_MAX / 1000000)
1072a9643ea8Slogwang delta_ticks = howmany(time_change->tv_sec * 1000000 +
1073a9643ea8Slogwang time_change->tv_usec, tick) + 1;
1074a9643ea8Slogwang else if (time_change->tv_sec <= LONG_MAX / hz)
1075a9643ea8Slogwang delta_ticks = time_change->tv_sec * hz +
1076a9643ea8Slogwang howmany(time_change->tv_usec, tick) + 1;
1077a9643ea8Slogwang else
1078a9643ea8Slogwang delta_ticks = LONG_MAX;
1079a9643ea8Slogwang
1080a9643ea8Slogwang if (delta_ticks > INT_MAX)
1081a9643ea8Slogwang delta_ticks = INT_MAX;
1082a9643ea8Slogwang
1083a9643ea8Slogwang /*
1084a9643ea8Slogwang * Now rip through the timer calltodo list looking for timers
1085a9643ea8Slogwang * to expire.
1086a9643ea8Slogwang */
1087a9643ea8Slogwang
1088a9643ea8Slogwang /* don't collide with softclock() */
1089a9643ea8Slogwang CC_LOCK(cc);
1090a9643ea8Slogwang for (p = calltodo.c_next; p != NULL; p = p->c_next) {
1091a9643ea8Slogwang p->c_time -= delta_ticks;
1092a9643ea8Slogwang
1093a9643ea8Slogwang /* Break if the timer had more time on it than delta_ticks */
1094a9643ea8Slogwang if (p->c_time > 0)
1095a9643ea8Slogwang break;
1096a9643ea8Slogwang
1097a9643ea8Slogwang /* take back the ticks the timer didn't use (p->c_time <= 0) */
1098a9643ea8Slogwang delta_ticks = -p->c_time;
1099a9643ea8Slogwang }
1100a9643ea8Slogwang CC_UNLOCK(cc);
1101a9643ea8Slogwang
1102a9643ea8Slogwang return;
1103a9643ea8Slogwang }
1104a9643ea8Slogwang #endif /* APM_FIXUP_CALLTODO */
1105a9643ea8Slogwang
1106a9643ea8Slogwang static int
flssbt(sbintime_t sbt)1107a9643ea8Slogwang flssbt(sbintime_t sbt)
1108a9643ea8Slogwang {
1109a9643ea8Slogwang
1110a9643ea8Slogwang sbt += (uint64_t)sbt >> 1;
1111a9643ea8Slogwang if (sizeof(long) >= sizeof(sbintime_t))
1112a9643ea8Slogwang return (flsl(sbt));
1113a9643ea8Slogwang if (sbt >= SBT_1S)
1114a9643ea8Slogwang return (flsl(((uint64_t)sbt) >> 32) + 32);
1115a9643ea8Slogwang return (flsl(sbt));
1116a9643ea8Slogwang }
1117a9643ea8Slogwang
1118a9643ea8Slogwang /*
1119a9643ea8Slogwang * Dump immediate statistic snapshot of the scheduled callouts.
1120a9643ea8Slogwang */
1121a9643ea8Slogwang static int
sysctl_kern_callout_stat(SYSCTL_HANDLER_ARGS)1122a9643ea8Slogwang sysctl_kern_callout_stat(SYSCTL_HANDLER_ARGS)
1123a9643ea8Slogwang {
1124a9643ea8Slogwang struct callout *tmp;
1125a9643ea8Slogwang struct callout_cpu *cc;
1126a9643ea8Slogwang struct callout_list *sc;
11275e5c25c3Slogwang int st, maxt, tick, now;
11285e5c25c3Slogwang sbintime_t medt;
11295e5c25c3Slogwang int ct[64], ccpbk[32];
1130a9643ea8Slogwang int error, val, i, count, tcum, pcum, maxc, c, medc;
1131a9643ea8Slogwang
1132a9643ea8Slogwang val = 0;
1133a9643ea8Slogwang error = sysctl_handle_int(oidp, &val, 0, req);
1134a9643ea8Slogwang if (error != 0 || req->newptr == NULL)
1135a9643ea8Slogwang return (error);
1136a9643ea8Slogwang count = maxc = 0;
11375e5c25c3Slogwang st = maxt = 0;
1138a9643ea8Slogwang bzero(ccpbk, sizeof(ccpbk));
1139a9643ea8Slogwang bzero(ct, sizeof(ct));
11405e5c25c3Slogwang now = ticks;
11415e5c25c3Slogwang
1142a9643ea8Slogwang cc = CC_CPU(timeout_cpu);
1143a9643ea8Slogwang CC_LOCK(cc);
1144a9643ea8Slogwang for (i = 0; i < callwheelsize; i++) {
1145a9643ea8Slogwang sc = &cc->cc_callwheel[i];
1146a9643ea8Slogwang c = 0;
1147a9643ea8Slogwang LIST_FOREACH(tmp, sc, c_links.le) {
1148a9643ea8Slogwang c++;
11495e5c25c3Slogwang tick = tmp->c_time - now;
11505e5c25c3Slogwang if (tick < 0)
11515e5c25c3Slogwang tick = 0;
11525e5c25c3Slogwang st += tick*(1000/hz);
11535e5c25c3Slogwang if (tick > maxt)
11545e5c25c3Slogwang maxt = tick;
11555e5c25c3Slogwang ct[flssbt(tick)]++;
1156a9643ea8Slogwang }
1157a9643ea8Slogwang if (c > maxc)
1158a9643ea8Slogwang maxc = c;
1159a9643ea8Slogwang ccpbk[fls(c + c / 2)]++;
1160a9643ea8Slogwang count += c;
1161a9643ea8Slogwang }
1162a9643ea8Slogwang CC_UNLOCK(cc);
1163a9643ea8Slogwang
1164a9643ea8Slogwang for (i = 0, tcum = 0; i < 64 && tcum < count / 2; i++)
1165a9643ea8Slogwang tcum += ct[i];
1166a9643ea8Slogwang medt = (i >= 2) ? (((sbintime_t)1) << (i - 2)) : 0;
1167a9643ea8Slogwang for (i = 0, c = 0; i < 32 && c < count / 2; i++)
1168a9643ea8Slogwang c += ccpbk[i];
1169a9643ea8Slogwang medc = (i >= 2) ? (1 << (i - 2)) : 0;
1170a9643ea8Slogwang
1171a9643ea8Slogwang printf("Scheduled callouts statistic snapshot:\n");
1172a9643ea8Slogwang printf(" Callouts: %6d Buckets: %6d*%-3d Bucket size: 0.%06ds\n",
1173a9643ea8Slogwang count, callwheelsize, mp_ncpus, 1000000 >> CC_HASH_SHIFT);
1174a9643ea8Slogwang printf(" C/Bk: med %5d avg %6d.%06jd max %6d\n",
1175a9643ea8Slogwang medc,
1176a9643ea8Slogwang count / callwheelsize / mp_ncpus,
1177a9643ea8Slogwang (uint64_t)count * 1000000 / callwheelsize / mp_ncpus % 1000000,
1178a9643ea8Slogwang maxc);
11795e5c25c3Slogwang printf(" Time: med %5jd.%06jds avg %6d.%06ds max %ds\n",
1180a9643ea8Slogwang medt / SBT_1S, (medt & 0xffffffff) * 1000000 >> 32,
11815e5c25c3Slogwang st / count / 1000, (st / count) % 1000, maxt);
11825e5c25c3Slogwang printf(" Distribution: \tbuckets\t time\t tcum\n");
1183a9643ea8Slogwang for (i = 0, tcum = pcum = 0; i < 64; i++) {
11845e5c25c3Slogwang if (ct[i] == 0)
1185a9643ea8Slogwang continue;
11865e5c25c3Slogwang sbintime_t t;
1187a9643ea8Slogwang t = (i != 0) ? (((sbintime_t)1) << (i - 1)) : 0;
1188a9643ea8Slogwang tcum += ct[i];
11895e5c25c3Slogwang printf(" %10jd.%06jds\t 2**%d\t%7d\t%7d\n",
1190a9643ea8Slogwang t / SBT_1S, (t & 0xffffffff) * 1000000 >> 32,
11915e5c25c3Slogwang i - 1 - (32 - CC_HASH_SHIFT), ct[i], tcum);
1192a9643ea8Slogwang }
1193a9643ea8Slogwang return (error);
1194a9643ea8Slogwang }
1195a9643ea8Slogwang SYSCTL_PROC(_kern, OID_AUTO, callout_stat,
1196a9643ea8Slogwang CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
1197a9643ea8Slogwang 0, 0, sysctl_kern_callout_stat, "I",
1198a9643ea8Slogwang "Dump immediate statistic snapshot of the scheduled callouts");
1199a9643ea8Slogwang
1200a9643ea8Slogwang #ifdef FSTACK
1201a9643ea8Slogwang void ff_hardclock(void);
1202a9643ea8Slogwang
1203a9643ea8Slogwang void
ff_hardclock(void)1204a9643ea8Slogwang ff_hardclock(void)
1205a9643ea8Slogwang {
1206a9643ea8Slogwang atomic_add_int(&ticks, 1);
12075e5c25c3Slogwang callout_tick();
1208a9643ea8Slogwang tc_ticktock(1);
1209a9643ea8Slogwang cpu_tick_calibration();
1210a9643ea8Slogwang
1211a9643ea8Slogwang #ifdef DEVICE_POLLING
1212a9643ea8Slogwang hardclock_device_poll(); /* this is very short and quick */
1213a9643ea8Slogwang #endif /* DEVICE_POLLING */
1214a9643ea8Slogwang }
1215a9643ea8Slogwang
1216a9643ea8Slogwang static unsigned int
ff_tc_get_timecount(struct timecounter * tc)1217a9643ea8Slogwang ff_tc_get_timecount(struct timecounter *tc)
1218a9643ea8Slogwang {
121939be5a50Slogwang uint64_t ns;
122039be5a50Slogwang ns = ff_get_tsc_ns();
122139be5a50Slogwang return ((ns * tc->tc_frequency) / ff_NSEC_PER_SEC);
1222a9643ea8Slogwang }
1223a9643ea8Slogwang
1224a9643ea8Slogwang static struct timecounter ff_timecounter = {
12251fdd2a6eSlogwang ff_tc_get_timecount, 0, ~0u, 100, "ff_clock", 1
1226a9643ea8Slogwang };
1227a9643ea8Slogwang
1228a9643ea8Slogwang static void
ff_tc_init(void)1229a9643ea8Slogwang ff_tc_init(void)
1230a9643ea8Slogwang {
1231a9643ea8Slogwang ff_timecounter.tc_frequency = hz;
1232a9643ea8Slogwang tc_init(&ff_timecounter);
1233a9643ea8Slogwang }
1234a9643ea8Slogwang SYSINIT(ff_tc, SI_SUB_SMP, SI_ORDER_ANY, ff_tc_init, NULL);
1235a9643ea8Slogwang #endif
1236