1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3 * This file and its contents are supplied under the terms of the
4 * Common Development and Distribution License ("CDDL"), version 1.0.
5 * You may only use this file in accordance with the terms of version
6 * 1.0 of the CDDL.
7 *
8 * A full copy of the text of the CDDL should have accompanied this
9 * source. A copy of the CDDL is also available via the Internet at
10 * https://opensource.org/license/CDDL-1.0.
11 */
12 /*
13 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
14 * Use is subject to license terms.
15 */
16
17 #include <sys/types.h>
18 #include <sys/param.h>
19 #include <sys/time.h>
20 #include <sys/sysmacros.h>
21 #include <sys/systm.h>
22 #include <sys/proc.h>
23 #include <sys/mutex.h>
24 #include <sys/condvar.h>
25 #include <sys/callb.h>
26 #include <sys/kmem.h>
27 #include <sys/cmn_err.h>
28 #include <sys/debug.h>
29 #include <sys/kobj.h>
30 #include <sys/systm.h> /* for delay() */
31 #include <sys/taskq.h> /* For TASKQ_NAMELEN */
32 #include <sys/kernel.h>
33
34 #define CB_MAXNAME TASKQ_NAMELEN
35
36 /*
37 * The callb mechanism provides generic event scheduling/echoing.
38 * A callb function is registered and called on behalf of the event.
39 */
40 typedef struct callb {
41 struct callb *c_next; /* next in class or on freelist */
42 kthread_id_t c_thread; /* ptr to caller's thread struct */
43 char c_flag; /* info about the callb state */
44 uchar_t c_class; /* this callb's class */
45 kcondvar_t c_done_cv; /* signal callb completion */
46 boolean_t (*c_func)(void *, int);
47 /* cb function: returns true if ok */
48 void *c_arg; /* arg to c_func */
49 char c_name[CB_MAXNAME+1]; /* debug:max func name length */
50 } callb_t;
51
52 /*
53 * callb c_flag bitmap definitions
54 */
55 #define CALLB_FREE 0x0
56 #define CALLB_TAKEN 0x1
57 #define CALLB_EXECUTING 0x2
58
59 /*
60 * Basic structure for a callb table.
61 * All callbs are organized into different class groups described
62 * by ct_class array.
63 * The callbs within a class are single-linked and normally run by a
64 * serial execution.
65 */
66 typedef struct callb_table {
67 kmutex_t ct_lock; /* protect all callb states */
68 callb_t *ct_freelist; /* free callb structures */
69 boolean_t ct_busy; /* B_TRUE prevents additions */
70 kcondvar_t ct_busy_cv; /* to wait for not busy */
71 int ct_ncallb; /* num of callbs allocated */
72 callb_t *ct_first_cb[NCBCLASS]; /* ptr to 1st callb in a class */
73 } callb_table_t;
74
75 int callb_timeout_sec = CPR_KTHREAD_TIMEOUT_SEC;
76
77 static callb_id_t callb_add_common(boolean_t (*)(void *, int),
78 void *, int, char *, kthread_id_t);
79
80 static callb_table_t callb_table; /* system level callback table */
81 static callb_table_t *ct = &callb_table;
82 static kmutex_t callb_safe_mutex;
83 callb_cpr_t callb_cprinfo_safe = {
84 &callb_safe_mutex, CALLB_CPR_ALWAYS_SAFE, 0, {0, 0} };
85
86 /*
87 * Init all callb tables in the system.
88 */
89 static void
callb_init(void * dummy __unused)90 callb_init(void *dummy __unused)
91 {
92 callb_table.ct_busy = B_FALSE; /* mark table open for additions */
93 mutex_init(&callb_safe_mutex, NULL, MUTEX_DEFAULT, NULL);
94 mutex_init(&callb_table.ct_lock, NULL, MUTEX_DEFAULT, NULL);
95 }
96
97 static void
callb_fini(void * dummy __unused)98 callb_fini(void *dummy __unused)
99 {
100 callb_t *cp;
101 int i;
102
103 mutex_enter(&ct->ct_lock);
104 for (i = 0; i < 16; i++) {
105 while ((cp = ct->ct_freelist) != NULL) {
106 ct->ct_freelist = cp->c_next;
107 ct->ct_ncallb--;
108 kmem_free(cp, sizeof (callb_t));
109 }
110 if (ct->ct_ncallb == 0)
111 break;
112 /* Not all callbacks finished, waiting for the rest. */
113 mutex_exit(&ct->ct_lock);
114 tsleep(ct, 0, "callb", hz / 4);
115 mutex_enter(&ct->ct_lock);
116 }
117 if (ct->ct_ncallb > 0)
118 printf("%s: Leaked %d callbacks!\n", __func__, ct->ct_ncallb);
119 mutex_exit(&ct->ct_lock);
120 mutex_destroy(&callb_safe_mutex);
121 mutex_destroy(&callb_table.ct_lock);
122 }
123
124 /*
125 * callout_add() is called to register func() be called later.
126 */
127 static callb_id_t
callb_add_common(boolean_t (* func)(void * arg,int code),void * arg,int class,char * name,kthread_id_t t)128 callb_add_common(boolean_t (*func)(void *arg, int code),
129 void *arg, int class, char *name, kthread_id_t t)
130 {
131 callb_t *cp;
132
133 ASSERT3S(class, <, NCBCLASS);
134
135 mutex_enter(&ct->ct_lock);
136 while (ct->ct_busy)
137 cv_wait(&ct->ct_busy_cv, &ct->ct_lock);
138 if ((cp = ct->ct_freelist) == NULL) {
139 ct->ct_ncallb++;
140 cp = kmem_zalloc(sizeof (callb_t), KM_SLEEP);
141 }
142 ct->ct_freelist = cp->c_next;
143 cp->c_thread = t;
144 cp->c_func = func;
145 cp->c_arg = arg;
146 cp->c_class = (uchar_t)class;
147 cp->c_flag |= CALLB_TAKEN;
148 #ifdef ZFS_DEBUG
149 if (strlen(name) > CB_MAXNAME)
150 cmn_err(CE_WARN, "callb_add: name of callback function '%s' "
151 "too long -- truncated to %d chars",
152 name, CB_MAXNAME);
153 #endif
154 (void) strlcpy(cp->c_name, name, sizeof (cp->c_name));
155
156 /*
157 * Insert the new callb at the head of its class list.
158 */
159 cp->c_next = ct->ct_first_cb[class];
160 ct->ct_first_cb[class] = cp;
161
162 mutex_exit(&ct->ct_lock);
163 return ((callb_id_t)cp);
164 }
165
166 /*
167 * The default function to add an entry to the callback table. Since
168 * it uses curthread as the thread identifier to store in the table,
169 * it should be used for the normal case of a thread which is calling
170 * to add ITSELF to the table.
171 */
172 callb_id_t
callb_add(boolean_t (* func)(void * arg,int code),void * arg,int class,char * name)173 callb_add(boolean_t (*func)(void *arg, int code),
174 void *arg, int class, char *name)
175 {
176 return (callb_add_common(func, arg, class, name, curthread));
177 }
178
179 /*
180 * A special version of callb_add() above for use by threads which
181 * might be adding an entry to the table on behalf of some other
182 * thread (for example, one which is constructed but not yet running).
183 * In this version the thread id is an argument.
184 */
185 callb_id_t
callb_add_thread(boolean_t (* func)(void * arg,int code),void * arg,int class,char * name,kthread_id_t t)186 callb_add_thread(boolean_t (*func)(void *arg, int code),
187 void *arg, int class, char *name, kthread_id_t t)
188 {
189 return (callb_add_common(func, arg, class, name, t));
190 }
191
192 /*
193 * callout_delete() is called to remove an entry identified by id
194 * that was originally placed there by a call to callout_add().
195 * return -1 if fail to delete a callb entry otherwise return 0.
196 */
197 int
callb_delete(callb_id_t id)198 callb_delete(callb_id_t id)
199 {
200 callb_t **pp;
201 callb_t *me = (callb_t *)id;
202
203 mutex_enter(&ct->ct_lock);
204
205 for (;;) {
206 pp = &ct->ct_first_cb[me->c_class];
207 while (*pp != NULL && *pp != me)
208 pp = &(*pp)->c_next;
209
210 #ifdef ZFS_DEBUG
211 if (*pp != me) {
212 cmn_err(CE_WARN, "callb delete bogus entry 0x%p",
213 (void *)me);
214 mutex_exit(&ct->ct_lock);
215 return (-1);
216 }
217 #endif /* DEBUG */
218
219 /*
220 * It is not allowed to delete a callb in the middle of
221 * executing otherwise, the callb_execute() will be confused.
222 */
223 if (!(me->c_flag & CALLB_EXECUTING))
224 break;
225
226 cv_wait(&me->c_done_cv, &ct->ct_lock);
227 }
228 /* relink the class list */
229 *pp = me->c_next;
230
231 /* clean up myself and return the free callb to the head of freelist */
232 me->c_flag = CALLB_FREE;
233 me->c_next = ct->ct_freelist;
234 ct->ct_freelist = me;
235
236 mutex_exit(&ct->ct_lock);
237 return (0);
238 }
239
240 /*
241 * class: indicates to execute all callbs in the same class;
242 * code: optional argument for the callb functions.
243 * return: = 0: success
244 * != 0: ptr to string supplied when callback was registered
245 */
246 void *
callb_execute_class(int class,int code)247 callb_execute_class(int class, int code)
248 {
249 callb_t *cp;
250 void *ret = NULL;
251
252 ASSERT3S(class, <, NCBCLASS);
253
254 mutex_enter(&ct->ct_lock);
255
256 for (cp = ct->ct_first_cb[class];
257 cp != NULL && ret == NULL; cp = cp->c_next) {
258 while (cp->c_flag & CALLB_EXECUTING)
259 cv_wait(&cp->c_done_cv, &ct->ct_lock);
260 /*
261 * cont if the callb is deleted while we're sleeping
262 */
263 if (cp->c_flag == CALLB_FREE)
264 continue;
265 cp->c_flag |= CALLB_EXECUTING;
266
267 #ifdef CALLB_DEBUG
268 printf("callb_execute: name=%s func=%p arg=%p\n",
269 cp->c_name, (void *)cp->c_func, (void *)cp->c_arg);
270 #endif /* CALLB_DEBUG */
271
272 mutex_exit(&ct->ct_lock);
273 /* If callback function fails, pass back client's name */
274 if (!(*cp->c_func)(cp->c_arg, code))
275 ret = cp->c_name;
276 mutex_enter(&ct->ct_lock);
277
278 cp->c_flag &= ~CALLB_EXECUTING;
279 cv_broadcast(&cp->c_done_cv);
280 }
281 mutex_exit(&ct->ct_lock);
282 return (ret);
283 }
284
285 /*
286 * callers make sure no recursive entries to this func.
287 * dp->cc_lockp is registered by callb_add to protect callb_cpr_t structure.
288 *
289 * When calling to stop a kernel thread (code == CB_CODE_CPR_CHKPT) we
290 * use a cv_timedwait() in case the kernel thread is blocked.
291 *
292 * Note that this is a generic callback handler for daemon CPR and
293 * should NOT be changed to accommodate any specific requirement in a daemon.
294 * Individual daemons that require changes to the handler shall write
295 * callback routines in their own daemon modules.
296 */
297 boolean_t
callb_generic_cpr(void * arg,int code)298 callb_generic_cpr(void *arg, int code)
299 {
300 callb_cpr_t *cp = (callb_cpr_t *)arg;
301 clock_t ret = 0; /* assume success */
302
303 mutex_enter(cp->cc_lockp);
304
305 switch (code) {
306 case CB_CODE_CPR_CHKPT:
307 cp->cc_events |= CALLB_CPR_START;
308 #ifdef CPR_NOT_THREAD_SAFE
309 while (!(cp->cc_events & CALLB_CPR_SAFE))
310 /* cv_timedwait() returns -1 if it times out. */
311 if ((ret = cv_reltimedwait(&cp->cc_callb_cv,
312 cp->cc_lockp, (callb_timeout_sec * hz),
313 TR_CLOCK_TICK)) == -1)
314 break;
315 #endif
316 break;
317
318 case CB_CODE_CPR_RESUME:
319 cp->cc_events &= ~CALLB_CPR_START;
320 cv_signal(&cp->cc_stop_cv);
321 break;
322 }
323 mutex_exit(cp->cc_lockp);
324 return (ret != -1);
325 }
326
327 /*
328 * The generic callback function associated with kernel threads which
329 * are always considered safe.
330 */
331 boolean_t
callb_generic_cpr_safe(void * arg,int code)332 callb_generic_cpr_safe(void *arg, int code)
333 {
334 (void) arg, (void) code;
335 return (B_TRUE);
336 }
337 /*
338 * Prevent additions to callback table.
339 */
340 void
callb_lock_table(void)341 callb_lock_table(void)
342 {
343 mutex_enter(&ct->ct_lock);
344 ASSERT(!ct->ct_busy);
345 ct->ct_busy = B_TRUE;
346 mutex_exit(&ct->ct_lock);
347 }
348
349 /*
350 * Allow additions to callback table.
351 */
352 void
callb_unlock_table(void)353 callb_unlock_table(void)
354 {
355 mutex_enter(&ct->ct_lock);
356 ASSERT(ct->ct_busy);
357 ct->ct_busy = B_FALSE;
358 cv_broadcast(&ct->ct_busy_cv);
359 mutex_exit(&ct->ct_lock);
360 }
361
362 SYSINIT(sol_callb, SI_SUB_DRIVERS, SI_ORDER_FIRST, callb_init, NULL);
363 SYSUNINIT(sol_callb, SI_SUB_DRIVERS, SI_ORDER_FIRST, callb_fini, NULL);
364