| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
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. |
| @@ -49,27 +49,27 @@ | | | @@ -49,27 +49,27 @@ |
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 |
| @@ -174,27 +174,26 @@ struct callout_cpu { | | | @@ -174,27 +174,26 @@ struct callout_cpu { |
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 |
186 | static struct callout_cpu ccb; | | 186 | static struct callout_cpu ccb; |
187 | static struct cpu_info cib; | | | |
188 | #endif | | 187 | #endif |
189 | | | 188 | |
190 | #ifndef CRASH /* _KERNEL */ | | 189 | #ifndef CRASH /* _KERNEL */ |
191 | static void callout_softclock(void *); | | 190 | static void callout_softclock(void *); |
192 | static void callout_wait(callout_impl_t *, void *, kmutex_t *); | | 191 | static void callout_wait(callout_impl_t *, void *, kmutex_t *); |
193 | | | 192 | |
194 | static struct callout_cpu callout_cpu0 __cacheline_aligned; | | 193 | static struct callout_cpu callout_cpu0 __cacheline_aligned; |
195 | static void *callout_sih __read_mostly; | | 194 | static void *callout_sih __read_mostly; |
196 | | | 195 | |
197 | static inline kmutex_t * | | 196 | static inline kmutex_t * |
198 | callout_lock(callout_impl_t *c) | | 197 | callout_lock(callout_impl_t *c) |
199 | { | | 198 | { |
200 | struct callout_cpu *cc; | | 199 | struct callout_cpu *cc; |
| @@ -843,29 +842,31 @@ db_show_callout(db_expr_t addr, bool had | | | @@ -843,29 +842,31 @@ db_show_callout(db_expr_t addr, bool had |
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 */ |