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.
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.
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]
22
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23
* Use is subject to license terms.
29
#include <sys/kcondvar.h>
36
* definitions of callback classes (c_class)
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.
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.
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
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
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 */
72
* CB_CL_CPR_DAEMON class specific definitions are given below:
76
* code for CPR callb_execute_class
78
#define CB_CODE_CPR_CHKPT 0
79
#define CB_CODE_CPR_RESUME 1
81
typedef void * callb_id_t;
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.
87
typedef 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 */
96
* cc_events definitions
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 */
103
* Used when checking that all kernel threads are stopped.
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 */
114
* CALLB_CPR_INIT macro is used by kernel threads to add their entry to
115
* the callback table and perform other initialization. It automatically
116
* adds the thread as being in the callback class CB_CL_CPR_DAEMON.
118
* cp - ptr to the callb_cpr_t structure for this kernel thread
120
* lockp - pointer to mutex protecting the callb_cpr_t stuct
122
* func - pointer to the callback function for this kernel thread.
123
* It has the prototype boolean_t <func>(void *arg, int code)
124
* where: arg - ptr to the callb_cpr_t structure
125
* code - not used for this type of callback
126
* returns: B_TRUE if successful; B_FALSE if unsuccessful.
128
* name - a string giving the name of the kernel thread
130
* Note: lockp is the lock to protect the callb_cpr_t (cp) structure
131
* later on. No lock held is needed for this initialization.
133
#define CALLB_CPR_INIT(cp, lockp, func, name) { \
134
strlcpy(curthread->td_name, (name), \
135
sizeof(curthread->td_name)); \
136
bzero((caddr_t)(cp), sizeof (callb_cpr_t)); \
137
(cp)->cc_lockp = lockp; \
138
(cp)->cc_id = callb_add(func, (void *)(cp), \
139
CB_CL_CPR_DAEMON, name); \
140
cv_init(&(cp)->cc_callb_cv, NULL, CV_DEFAULT, NULL); \
141
cv_init(&(cp)->cc_stop_cv, NULL, CV_DEFAULT, NULL); \
145
#define CALLB_CPR_ASSERT(cp) ASSERT(MUTEX_HELD((cp)->cc_lockp));
147
#define CALLB_CPR_ASSERT(cp)
150
* Some threads (like the idle threads) do not adhere to the callback
151
* protocol and are always considered safe. Such threads must never exit.
152
* They register their presence by calling this macro during their
156
* t - thread pointer of the client kernel thread
157
* name - a string giving the name of the kernel thread
159
#define CALLB_CPR_INIT_SAFE(t, name) { \
160
(void) callb_add_thread(callb_generic_cpr_safe, \
161
(void *) &callb_cprinfo_safe, CB_CL_CPR_DAEMON, \
165
* The lock to protect cp's content must be held before
166
* calling the following two macros.
168
* Any code region between CALLB_CPR_SAFE_BEGIN and CALLB_CPR_SAFE_END
169
* is safe for checkpoint/resume.
171
#define CALLB_CPR_SAFE_BEGIN(cp) { \
172
CALLB_CPR_ASSERT(cp) \
173
(cp)->cc_events |= CALLB_CPR_SAFE; \
174
if ((cp)->cc_events & CALLB_CPR_START) \
175
cv_signal(&(cp)->cc_callb_cv); \
177
#define CALLB_CPR_SAFE_END(cp, lockp) { \
178
CALLB_CPR_ASSERT(cp) \
179
while ((cp)->cc_events & CALLB_CPR_START) \
180
cv_wait(&(cp)->cc_stop_cv, lockp); \
181
(cp)->cc_events &= ~CALLB_CPR_SAFE; \
184
* cv_destroy is nop right now but may be needed in the future.
186
#define CALLB_CPR_EXIT(cp) { \
187
CALLB_CPR_ASSERT(cp) \
188
(cp)->cc_events |= CALLB_CPR_SAFE; \
189
if ((cp)->cc_events & CALLB_CPR_START) \
190
cv_signal(&(cp)->cc_callb_cv); \
191
mutex_exit((cp)->cc_lockp); \
192
(void) callb_delete((cp)->cc_id); \
193
cv_destroy(&(cp)->cc_callb_cv); \
194
cv_destroy(&(cp)->cc_stop_cv); \
197
extern callb_cpr_t callb_cprinfo_safe;
198
extern callb_id_t callb_add(boolean_t (*)(void *, int), void *, int, char *);
199
extern callb_id_t callb_add_thread(boolean_t (*)(void *, int),
200
void *, int, char *, kthread_id_t);
201
extern int callb_delete(callb_id_t);
202
extern void callb_execute(callb_id_t, int);
203
extern void *callb_execute_class(int, int);
204
extern boolean_t callb_generic_cpr(void *, int);
205
extern boolean_t callb_generic_cpr_safe(void *, int);
206
extern boolean_t callb_is_stopped(kthread_id_t, caddr_t *);
207
extern void callb_lock_table(void);
208
extern void callb_unlock_table(void);
215
#endif /* _SYS_CALLB_H */