]> git.proxmox.com Git - mirror_zfs.git/blame - include/os/freebsd/spl/sys/callb.h
Remove bcopy(), bzero(), bcmp()
[mirror_zfs.git] / include / os / freebsd / spl / sys / callb.h
CommitLineData
9f0a21e6
MM
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#ifndef _SYS_CALLB_H
27#define _SYS_CALLB_H
28
29#include <sys/condvar.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35/*
36 * definitions of callback classes (c_class)
37 *
38 * Callbacks belong in the same class if (1) their callback routines
39 * do the same kind of processing (ideally, using the same callback function)
40 * and (2) they can/should be executed at the same time in a cpr
41 * suspend/resume operation.
42 *
43 * Note: The DAEMON class, in particular, is for stopping kernel threads
44 * and nothing else. The CALLB_* macros below should be used to deal
45 * with kernel threads, and the callback function should be callb_generic_cpr.
46 * Another idiosyncrasy of the DAEMON class is that if a suspend operation
47 * fails, some of the callback functions may be called with the RESUME
48 * code which were never called with SUSPEND. Not a problem currently,
49 * but see bug 4201851.
50 */
51#define CB_CL_CPR_DAEMON 0
52#define CB_CL_CPR_VM 1
53#define CB_CL_CPR_CALLOUT 2
54#define CB_CL_CPR_OBP 3
55#define CB_CL_CPR_FB 4
56#define CB_CL_PANIC 5
57#define CB_CL_CPR_RPC 6
58#define CB_CL_CPR_PROMPRINTF 7
59#define CB_CL_UADMIN 8
60#define CB_CL_CPR_PM 9
61#define CB_CL_HALT 10
62#define CB_CL_CPR_DMA 11
63#define CB_CL_CPR_POST_USER 12
64#define CB_CL_UADMIN_PRE_VFS 13
65#define CB_CL_MDBOOT CB_CL_UADMIN
66#define CB_CL_ENTER_DEBUGGER 14
67#define CB_CL_CPR_POST_KERNEL 15
68#define CB_CL_CPU_DEEP_IDLE 16
69#define NCBCLASS 17 /* CHANGE ME if classes are added/removed */
70
71/*
72 * CB_CL_CPR_DAEMON class specific definitions are given below:
73 */
74
75/*
76 * code for CPR callb_execute_class
77 */
78#define CB_CODE_CPR_CHKPT 0
79#define CB_CODE_CPR_RESUME 1
80
81typedef void * callb_id_t;
82/*
83 * Per kernel thread structure for CPR daemon callbacks.
84 * Must be protected by either a existing lock in the daemon or
85 * a new lock created for such a purpose.
86 */
87typedef struct callb_cpr {
88 kmutex_t *cc_lockp; /* lock to protect this struct */
89 char cc_events; /* various events for CPR */
90 callb_id_t cc_id; /* callb id address */
91 kcondvar_t cc_callb_cv; /* cv for callback waiting */
92 kcondvar_t cc_stop_cv; /* cv to checkpoint block */
93} callb_cpr_t;
94
95/*
96 * cc_events definitions
97 */
98#define CALLB_CPR_START 1 /* a checkpoint request's started */
99#define CALLB_CPR_SAFE 2 /* thread is safe for CPR */
100#define CALLB_CPR_ALWAYS_SAFE 4 /* thread is ALWAYS safe for CPR */
101
102/*
103 * Used when checking that all kernel threads are stopped.
104 */
105#define CALLB_MAX_RETRY 3 /* when waiting for kthread to sleep */
106#define CALLB_THREAD_DELAY 10 /* ticks allowed to reach sleep */
107#define CPR_KTHREAD_TIMEOUT_SEC 90 /* secs before callback times out -- */
108 /* due to pwr mgmt of disks, make -- */
109 /* big enough for worst spinup time */
110
111/*
112 *
113 * CALLB_CPR_INIT macro is used by kernel threads to add their entry to
114 * the callback table and perform other initialization. It automatically
115 * adds the thread as being in the callback class CB_CL_CPR_DAEMON.
116 *
117 * cp - ptr to the callb_cpr_t structure for this kernel thread
118 *
dd4bc569 119 * lockp - pointer to mutex protecting the callb_cpr_t struct
9f0a21e6
MM
120 *
121 * func - pointer to the callback function for this kernel thread.
122 * It has the prototype boolean_t <func>(void *arg, int code)
123 * where: arg - ptr to the callb_cpr_t structure
124 * code - not used for this type of callback
125 * returns: B_TRUE if successful; B_FALSE if unsuccessful.
126 *
127 * name - a string giving the name of the kernel thread
128 *
129 * Note: lockp is the lock to protect the callb_cpr_t (cp) structure
130 * later on. No lock held is needed for this initialization.
131 */
132#define CALLB_CPR_INIT(cp, lockp, func, name) { \
133 strlcpy(curthread->td_name, (name), \
134 sizeof (curthread->td_name)); \
861166b0 135 memset(cp, 0, sizeof (callb_cpr_t)); \
9f0a21e6
MM
136 (cp)->cc_lockp = lockp; \
137 (cp)->cc_id = callb_add(func, (void *)(cp), \
138 CB_CL_CPR_DAEMON, name); \
139 cv_init(&(cp)->cc_callb_cv, NULL, CV_DEFAULT, NULL); \
140 cv_init(&(cp)->cc_stop_cv, NULL, CV_DEFAULT, NULL); \
141 }
142
143#ifndef __lock_lint
144#define CALLB_CPR_ASSERT(cp) ASSERT(MUTEX_HELD((cp)->cc_lockp));
145#else
146#define CALLB_CPR_ASSERT(cp)
147#endif
148/*
149 * Some threads (like the idle threads) do not adhere to the callback
150 * protocol and are always considered safe. Such threads must never exit.
151 * They register their presence by calling this macro during their
152 * initialization.
153 *
154 * Args:
155 * t - thread pointer of the client kernel thread
156 * name - a string giving the name of the kernel thread
157 */
158#define CALLB_CPR_INIT_SAFE(t, name) { \
159 (void) callb_add_thread(callb_generic_cpr_safe, \
160 (void *) &callb_cprinfo_safe, CB_CL_CPR_DAEMON, \
161 name, t); \
162 }
163/*
164 * The lock to protect cp's content must be held before
165 * calling the following two macros.
166 *
167 * Any code region between CALLB_CPR_SAFE_BEGIN and CALLB_CPR_SAFE_END
168 * is safe for checkpoint/resume.
169 */
170#define CALLB_CPR_SAFE_BEGIN(cp) { \
171 CALLB_CPR_ASSERT(cp) \
172 (cp)->cc_events |= CALLB_CPR_SAFE; \
173 if ((cp)->cc_events & CALLB_CPR_START) \
174 cv_signal(&(cp)->cc_callb_cv); \
175 }
176#define CALLB_CPR_SAFE_END(cp, lockp) { \
177 CALLB_CPR_ASSERT(cp) \
178 while ((cp)->cc_events & CALLB_CPR_START) \
179 cv_wait(&(cp)->cc_stop_cv, lockp); \
180 (cp)->cc_events &= ~CALLB_CPR_SAFE; \
181 }
182/*
183 * cv_destroy is nop right now but may be needed in the future.
184 */
185#define CALLB_CPR_EXIT(cp) { \
186 CALLB_CPR_ASSERT(cp) \
187 (cp)->cc_events |= CALLB_CPR_SAFE; \
188 if ((cp)->cc_events & CALLB_CPR_START) \
189 cv_signal(&(cp)->cc_callb_cv); \
190 mutex_exit((cp)->cc_lockp); \
191 (void) callb_delete((cp)->cc_id); \
192 cv_destroy(&(cp)->cc_callb_cv); \
193 cv_destroy(&(cp)->cc_stop_cv); \
194 }
195
196extern callb_cpr_t callb_cprinfo_safe;
197extern callb_id_t callb_add(boolean_t (*)(void *, int), void *, int, char *);
198extern callb_id_t callb_add_thread(boolean_t (*)(void *, int),
199 void *, int, char *, kthread_id_t);
200extern int callb_delete(callb_id_t);
201extern void callb_execute(callb_id_t, int);
202extern void *callb_execute_class(int, int);
203extern boolean_t callb_generic_cpr(void *, int);
204extern boolean_t callb_generic_cpr_safe(void *, int);
205extern boolean_t callb_is_stopped(kthread_id_t, caddr_t *);
206extern void callb_lock_table(void);
207extern void callb_unlock_table(void);
208
209#ifdef __cplusplus
210}
211#endif
212
213#endif /* _SYS_CALLB_H */