callb.h revision 185029
1168404Spjd/*
2168404Spjd * CDDL HEADER START
3168404Spjd *
4168404Spjd * The contents of this file are subject to the terms of the
5168404Spjd * Common Development and Distribution License, Version 1.0 only
6168404Spjd * (the "License").  You may not use this file except in compliance
7168404Spjd * with the License.
8168404Spjd *
9168404Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10168404Spjd * or http://www.opensolaris.org/os/licensing.
11168404Spjd * See the License for the specific language governing permissions
12168404Spjd * and limitations under the License.
13168404Spjd *
14168404Spjd * When distributing Covered Code, include this CDDL HEADER in each
15168404Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16168404Spjd * If applicable, add the following below this CDDL HEADER, with the
17168404Spjd * fields enclosed by brackets "[]" replaced with your own identifying
18168404Spjd * information: Portions Copyright [yyyy] [name of copyright owner]
19168404Spjd *
20168404Spjd * CDDL HEADER END
21168404Spjd */
22168404Spjd/*
23168404Spjd * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24168404Spjd * Use is subject to license terms.
25168404Spjd */
26168404Spjd
27168404Spjd#ifndef	_SYS_CALLB_H
28168404Spjd#define	_SYS_CALLB_H
29168404Spjd
30185029Spjd#pragma ident	"@(#)callb.h	1.29	05/06/23 SMI"
31168404Spjd
32185029Spjd#include <sys/kcondvar.h>
33168404Spjd
34168404Spjd#ifdef	__cplusplus
35168404Spjdextern "C" {
36168404Spjd#endif
37168404Spjd
38168404Spjd/*
39168404Spjd * definitions of callback classes (c_class)
40168404Spjd *
41168404Spjd * Callbacks belong in the same class if (1) their callback routines
42168404Spjd * do the same kind of processing (ideally, using the same callback function)
43168404Spjd * and (2) they can/should be executed at the same time in a cpr
44168404Spjd * suspend/resume operation.
45168404Spjd *
46168404Spjd * Note: The DAEMON class, in particular, is for stopping kernel threads
47168404Spjd * and nothing else.  The CALLB_* macros below should be used to deal
48168404Spjd * with kernel threads, and the callback function should be callb_generic_cpr.
49168404Spjd * Another idiosyncrasy of the DAEMON class is that if a suspend operation
50168404Spjd * fails, some of the callback functions may be called with the RESUME
51168404Spjd * code which were never called with SUSPEND.  Not a problem currently,
52168404Spjd * but see bug 4201851.
53168404Spjd */
54168404Spjd#define	CB_CL_CPR_DAEMON	0
55168404Spjd#define	CB_CL_CPR_VM		1
56168404Spjd#define	CB_CL_CPR_CALLOUT	2
57168404Spjd#define	CB_CL_CPR_OBP		3
58168404Spjd#define	CB_CL_CPR_FB		4
59168404Spjd#define	CB_CL_PANIC		5
60168404Spjd#define	CB_CL_CPR_RPC		6
61168404Spjd#define	CB_CL_CPR_PROMPRINTF	7
62168404Spjd#define	CB_CL_UADMIN		8
63168404Spjd#define	CB_CL_CPR_PM		9
64168404Spjd#define	CB_CL_HALT		10
65168404Spjd#define	CB_CL_CPR_DMA		11
66168404Spjd#define	CB_CL_CPR_POST_USER	12
67168404Spjd#define	CB_CL_UADMIN_PRE_VFS    13
68168404Spjd#define	CB_CL_MDBOOT		CB_CL_UADMIN
69168404Spjd#define	CB_CL_ENTER_DEBUGGER	14
70168404Spjd#define	CB_CL_CPR_POST_KERNEL	15
71168404Spjd#define	NCBCLASS		16 /* CHANGE ME if classes are added/removed */
72168404Spjd
73168404Spjd/*
74168404Spjd * CB_CL_CPR_DAEMON class specific definitions are given below:
75168404Spjd */
76168404Spjd
77168404Spjd/*
78168404Spjd * code for CPR callb_execute_class
79168404Spjd */
80168404Spjd#define	CB_CODE_CPR_CHKPT	0
81168404Spjd#define	CB_CODE_CPR_RESUME	1
82168404Spjd
83168404Spjdtypedef	void *		callb_id_t;
84168404Spjd/*
85168404Spjd * Per kernel thread structure for CPR daemon callbacks.
86168404Spjd * Must be protected by either a existing lock in the daemon or
87168404Spjd * a new lock created for such a purpose.
88168404Spjd */
89168404Spjdtypedef struct callb_cpr {
90168404Spjd	kmutex_t	*cc_lockp;	/* lock to protect this struct */
91168404Spjd	char		cc_events;	/* various events for CPR */
92168404Spjd	callb_id_t	cc_id;		/* callb id address */
93168404Spjd	kcondvar_t	cc_callb_cv;	/* cv for callback waiting */
94168404Spjd	kcondvar_t	cc_stop_cv;	/* cv to checkpoint block */
95168404Spjd} callb_cpr_t;
96168404Spjd
97168404Spjd/*
98168404Spjd * cc_events definitions
99168404Spjd */
100168404Spjd#define	CALLB_CPR_START		1	/* a checkpoint request's started */
101168404Spjd#define	CALLB_CPR_SAFE		2	/* thread is safe for CPR */
102168404Spjd#define	CALLB_CPR_ALWAYS_SAFE	4	/* thread is ALWAYS safe for CPR */
103168404Spjd
104168404Spjd/*
105168404Spjd * Used when checking that all kernel threads are stopped.
106168404Spjd */
107168404Spjd#define	CALLB_MAX_RETRY		3	/* when waiting for kthread to sleep */
108168404Spjd#define	CALLB_THREAD_DELAY	10	/* ticks allowed to reach sleep */
109168404Spjd#define	CPR_KTHREAD_TIMEOUT_SEC	90	/* secs before callback times out -- */
110168404Spjd					/* due to pwr mgmt of disks, make -- */
111168404Spjd					/* big enough for worst spinup time */
112168404Spjd
113168404Spjd#ifdef  _KERNEL
114168404Spjd/*
115168404Spjd *
116168404Spjd * CALLB_CPR_INIT macro is used by kernel threads to add their entry to
117168404Spjd * the callback table and perform other initialization.  It automatically
118168404Spjd * adds the thread as being in the callback class CB_CL_CPR_DAEMON.
119168404Spjd *
120168404Spjd *	cp    - ptr to the callb_cpr_t structure for this kernel thread
121168404Spjd *
122168404Spjd *	lockp - pointer to mutex protecting the callb_cpr_t stuct
123168404Spjd *
124168404Spjd *	func  - pointer to the callback function for this kernel thread.
125168404Spjd *		It has the prototype boolean_t <func>(void *arg, int code)
126168404Spjd *		where: arg	- ptr to the callb_cpr_t structure
127168404Spjd *		       code	- not used for this type of callback
128168404Spjd *		returns: B_TRUE if successful; B_FALSE if unsuccessful.
129168404Spjd *
130168404Spjd *	name  - a string giving the name of the kernel thread
131168404Spjd *
132168404Spjd * Note: lockp is the lock to protect the callb_cpr_t (cp) structure
133168404Spjd * later on.  No lock held is needed for this initialization.
134168404Spjd */
135168404Spjd#define	CALLB_CPR_INIT(cp, lockp, func, name)	{			\
136185029Spjd		strlcpy(curthread->td_name, (name),			\
137185029Spjd		    sizeof(curthread->td_name));			\
138185029Spjd		strlcpy(curthread->td_proc->p_comm, (name),		\
139185029Spjd		    sizeof(curthread->td_proc->p_comm));		\
140168404Spjd		bzero((caddr_t)(cp), sizeof (callb_cpr_t));		\
141168404Spjd		(cp)->cc_lockp = lockp;					\
142168404Spjd		(cp)->cc_id = callb_add(func, (void *)(cp),		\
143168404Spjd			CB_CL_CPR_DAEMON, name);			\
144185029Spjd		cv_init(&(cp)->cc_callb_cv, NULL, CV_DEFAULT, NULL);	\
145185029Spjd		cv_init(&(cp)->cc_stop_cv, NULL, CV_DEFAULT, NULL);	\
146168404Spjd	}
147168404Spjd
148168404Spjd#ifndef __lock_lint
149168404Spjd#define	CALLB_CPR_ASSERT(cp)	ASSERT(MUTEX_HELD((cp)->cc_lockp));
150168404Spjd#else
151168404Spjd#define	CALLB_CPR_ASSERT(cp)
152168404Spjd#endif
153168404Spjd/*
154168404Spjd * Some threads (like the idle threads) do not adhere to the callback
155168404Spjd * protocol and are always considered safe.  Such threads must never exit.
156168404Spjd * They register their presence by calling this macro during their
157168404Spjd * initialization.
158168404Spjd *
159168404Spjd * Args:
160168404Spjd *	t	- thread pointer of the client kernel thread
161168404Spjd *	name	- a string giving the name of the kernel thread
162168404Spjd */
163168404Spjd#define	CALLB_CPR_INIT_SAFE(t, name) {					\
164168404Spjd		(void) callb_add_thread(callb_generic_cpr_safe,		\
165168404Spjd		(void *) &callb_cprinfo_safe, CB_CL_CPR_DAEMON,		\
166168404Spjd		    name, t);						\
167168404Spjd	}
168168404Spjd/*
169168404Spjd * The lock to protect cp's content must be held before
170168404Spjd * calling the following two macros.
171168404Spjd *
172168404Spjd * Any code region between CALLB_CPR_SAFE_BEGIN and CALLB_CPR_SAFE_END
173168404Spjd * is safe for checkpoint/resume.
174168404Spjd */
175168404Spjd#define	CALLB_CPR_SAFE_BEGIN(cp) { 			\
176168404Spjd		CALLB_CPR_ASSERT(cp)			\
177168404Spjd		(cp)->cc_events |= CALLB_CPR_SAFE;	\
178168404Spjd		if ((cp)->cc_events & CALLB_CPR_START)	\
179168404Spjd			cv_signal(&(cp)->cc_callb_cv);	\
180168404Spjd	}
181168404Spjd#define	CALLB_CPR_SAFE_END(cp, lockp) {				\
182168404Spjd		CALLB_CPR_ASSERT(cp)				\
183168404Spjd		while ((cp)->cc_events & CALLB_CPR_START)	\
184168404Spjd			cv_wait(&(cp)->cc_stop_cv, lockp);	\
185168404Spjd		(cp)->cc_events &= ~CALLB_CPR_SAFE;		\
186168404Spjd	}
187168404Spjd/*
188168404Spjd * cv_destroy is nop right now but may be needed in the future.
189168404Spjd */
190168404Spjd#define	CALLB_CPR_EXIT(cp) {				\
191168404Spjd		CALLB_CPR_ASSERT(cp)			\
192168404Spjd		(cp)->cc_events |= CALLB_CPR_SAFE;	\
193168404Spjd		if ((cp)->cc_events & CALLB_CPR_START)	\
194168404Spjd			cv_signal(&(cp)->cc_callb_cv);	\
195168404Spjd		mutex_exit((cp)->cc_lockp);		\
196168404Spjd		(void) callb_delete((cp)->cc_id);	\
197168404Spjd		cv_destroy(&(cp)->cc_callb_cv);		\
198168404Spjd		cv_destroy(&(cp)->cc_stop_cv);		\
199168404Spjd	}
200168404Spjd
201168404Spjdextern callb_cpr_t callb_cprinfo_safe;
202168404Spjdextern callb_id_t callb_add(boolean_t  (*)(void *, int), void *, int, char *);
203168404Spjdextern callb_id_t callb_add_thread(boolean_t (*)(void *, int),
204168404Spjd    void *, int, char *, kthread_id_t);
205168404Spjdextern int	callb_delete(callb_id_t);
206168404Spjdextern void	callb_execute(callb_id_t, int);
207168404Spjdextern void	*callb_execute_class(int, int);
208168404Spjdextern boolean_t callb_generic_cpr(void *, int);
209168404Spjdextern boolean_t callb_generic_cpr_safe(void *, int);
210168404Spjdextern boolean_t callb_is_stopped(kthread_id_t, caddr_t *);
211168404Spjdextern void	callb_lock_table(void);
212168404Spjdextern void	callb_unlock_table(void);
213168404Spjd#endif
214168404Spjd
215168404Spjd#ifdef	__cplusplus
216168404Spjd}
217168404Spjd#endif
218168404Spjd
219168404Spjd#endif	/* _SYS_CALLB_H */
220