~ubuntu-branches/ubuntu/trusty/ctfutils/trusty-proposed

« back to all changes in this revision

Viewing changes to sys/cddl/contrib/opensolaris/uts/common/sys/callb.h

  • Committer: Package Import Robot
  • Author(s): Robert Millan
  • Date: 2013-11-09 17:07:06 UTC
  • Revision ID: package-import@ubuntu.com-20131109170706-kacr6nvpkbhxsk81
Tags: upstream-9.2
ImportĀ upstreamĀ versionĀ 9.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/kcondvar.h>
 
30
 
 
31
#ifdef  __cplusplus
 
32
extern "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
 
 
81
typedef 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
 */
 
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 */
 
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
#ifdef  _KERNEL
 
112
/*
 
113
 *
 
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.
 
117
 *
 
118
 *      cp    - ptr to the callb_cpr_t structure for this kernel thread
 
119
 *
 
120
 *      lockp - pointer to mutex protecting the callb_cpr_t stuct
 
121
 *
 
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.
 
127
 *
 
128
 *      name  - a string giving the name of the kernel thread
 
129
 *
 
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.
 
132
 */
 
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);     \
 
142
        }
 
143
 
 
144
#ifndef __lock_lint
 
145
#define CALLB_CPR_ASSERT(cp)    ASSERT(MUTEX_HELD((cp)->cc_lockp));
 
146
#else
 
147
#define CALLB_CPR_ASSERT(cp)
 
148
#endif
 
149
/*
 
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
 
153
 * initialization.
 
154
 *
 
155
 * Args:
 
156
 *      t       - thread pointer of the client kernel thread
 
157
 *      name    - a string giving the name of the kernel thread
 
158
 */
 
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,         \
 
162
                    name, t);                                           \
 
163
        }
 
164
/*
 
165
 * The lock to protect cp's content must be held before
 
166
 * calling the following two macros.
 
167
 *
 
168
 * Any code region between CALLB_CPR_SAFE_BEGIN and CALLB_CPR_SAFE_END
 
169
 * is safe for checkpoint/resume.
 
170
 */
 
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);  \
 
176
        }
 
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;             \
 
182
        }
 
183
/*
 
184
 * cv_destroy is nop right now but may be needed in the future.
 
185
 */
 
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);          \
 
195
        }
 
196
 
 
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);
 
209
#endif
 
210
 
 
211
#ifdef  __cplusplus
 
212
}
 
213
#endif
 
214
 
 
215
#endif  /* _SYS_CALLB_H */