1 /*	$OpenBSD: rf_dag.h,v 1.4 2002/12/16 07:01:03 tdeval Exp $	*/
2 /*	$NetBSD: rf_dag.h,v 1.3 1999/02/05 00:06:07 oster Exp $	*/
3 
4 /*
5  * Copyright (c) 1995 Carnegie-Mellon University.
6  * All rights reserved.
7  *
8  * Author: William V. Courtright II, Mark Holland
9  *
10  * Permission to use, copy, modify and distribute this software and
11  * its documentation is hereby granted, provided that both the copyright
12  * notice and this permission notice appear in all copies of the
13  * software, derivative works or modified versions, and any portions
14  * thereof, and that both notices appear in supporting documentation.
15  *
16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19  *
20  * Carnegie Mellon requests users of this software to return to
21  *
22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
23  *  School of Computer Science
24  *  Carnegie Mellon University
25  *  Pittsburgh PA 15213-3890
26  *
27  * any improvements or extensions that they make and grant Carnegie the
28  * rights to redistribute these changes.
29  */
30 
31 /****************************************************************************
32  *                                                                          *
33  * dag.h -- header file for DAG-related data structures                     *
34  *                                                                          *
35  ****************************************************************************/
36 
37 #ifndef	_RF__RF_DAG_H_
38 #define	_RF__RF_DAG_H_
39 
40 #include "rf_types.h"
41 #include "rf_threadstuff.h"
42 #include "rf_alloclist.h"
43 #include "rf_stripelocks.h"
44 #include "rf_layout.h"
45 #include "rf_dagflags.h"
46 #include "rf_acctrace.h"
47 #include "rf_memchunk.h"
48 
49 #define	RF_THREAD_CONTEXT   0	/* We were invoked from thread context. */
50 #define	RF_INTR_CONTEXT     1	/* We were invoked from interrupt context. */
51 #define	RF_MAX_ANTECEDENTS 20	/* Max num of antecedents a node may possess. */
52 
53 #include <sys/buf.h>
54 
55 struct RF_PropHeader_s {	/* Structure for propagation of results. */
56 	int		 resultNum;	/* Bind result # resultNum. */
57 	int		 paramNum;	/* To parameter # paramNum. */
58 	RF_PropHeader_t	*next;		/* Linked list for multiple
59 					 * results/params. */
60 };
61 
62 typedef enum RF_NodeStatus_e {
63 	rf_bwd1,	/*
64 			 * Node is ready for undo logging
65 			 * (backward error recovery only).
66 			 */
67 	rf_bwd2,	/*
68 			 * Node has completed undo logging
69 			 * (backward error recovery only).
70 			 */
71 	rf_wait,	/* Node is waiting to be executed. */
72 	rf_fired,	/* Node is currently executing its do function. */
73 	rf_good,	/*
74 			 * Node successfully completed execution
75 			 * of its do function.
76 			 */
77 	rf_bad,		/*
78 			 * Node failed to successfully execute
79 			 * its do function.
80 			 */
81 	rf_skipped,	/*
82 			 * Not used anymore, used to imply a node
83 			 * was not executed.
84 			 */
85 	rf_recover,	/* Node is currently executing its undo function. */
86 	rf_panic,	/*
87 			 * Node failed to successfully execute
88 			 * its undo function.
89 			 */
90 	rf_undone	/* Node successfully executed its undo function. */
91 } RF_NodeStatus_t;
92 
93 /*
94  * These were used to control skipping a node.
95  * Now, these are only used as comments.
96  */
97 typedef enum RF_AntecedentType_e {
98 	rf_trueData,
99 	rf_antiData,
100 	rf_outputData,
101 	rf_control
102 } RF_AntecedentType_t;
103 #define	RF_DAG_PTRCACHESIZE	40
104 #define	RF_DAG_PARAMCACHESIZE	12
105 
106 typedef RF_uint8 RF_DagNodeFlags_t;
107 
108 struct RF_DagNode_s {
109 	RF_NodeStatus_t	  status;	/* Current status of this node. */
110 	int		(*doFunc) (RF_DagNode_t *);
111 					/* Normal function. */
112 	int		(*undoFunc) (RF_DagNode_t *);
113 					/* Func to remove effect of doFunc. */
114 	int		(*wakeFunc) (RF_DagNode_t *, int status);
115 					/*
116 					 * Func called when the node completes
117 					 * an I/O.
118 					 */
119 	int		  numParams;	/*
120 					 * Number of parameters required
121 					 * by *funcPtr.
122 					 */
123 	int		  numResults;	/*
124 					 * Number of results produced
125 					 * by *funcPtr.
126 					 */
127 	int		  numAntecedents; /* Number of antecedents. */
128 	int		  numAntDone;	/*
129 					 * Number of antecedents that
130 					 * have finished.
131 					 */
132 	int		  numSuccedents; /* Number of succedents. */
133 	int		  numSuccFired;	/*
134 					 * Incremented when a succedent
135 					 * is fired during forward execution.
136 					 */
137 	int		  numSuccDone;	/*
138 					 * Incremented when a succedent
139 					 * finishes during rollBackward.
140 					 */
141 	int		  commitNode;	/*
142 					 * Boolean flag - if true, this is
143 					 * a commit node.
144 					 */
145 	RF_DagNode_t	**succedents;	/*
146 					 * Succedents, array size
147 					 * numSuccedents.
148 					 */
149 	RF_DagNode_t	**antecedents;	/*
150 					 * Antecedents, array size
151 					 * numAntecedents.
152 					 */
153 	RF_AntecedentType_t antType[RF_MAX_ANTECEDENTS];
154 					/* Type of each antecedent. */
155 	void		**results;	/*
156 					 * Array of results produced
157 					 * by *funcPtr.
158 					 */
159 	RF_DagParam_t	 *params;	/*
160 					 * Array of parameters required
161 					 * by *funcPtr.
162 					 */
163 	RF_PropHeader_t	**propList;	/*
164 					 * Propagation list,
165 					 * size numSuccedents.
166 					 */
167 	RF_DagHeader_t	 *dagHdr;	/*
168 					 * Ptr to head of dag containing
169 					 * this node.
170 					 */
171 	void		 *dagFuncData;	/*
172 					 * Dag execution func uses this
173 					 * for whatever it wants.
174 					 */
175 	RF_DagNode_t	 *next;
176 	int		  nodeNum;	/* Used by PrintDAG for debug only. */
177 	int		  visited;	/*
178 					 * Used to avoid re-visiting
179 					 * nodes on DAG walks.
180 					 */
181 	/*
182 	 * ANY CODE THAT USES THIS FIELD MUST MAINTAIN THE PROPERTY THAT
183 	 * AFTER IT FINISHES, ALL VISITED FLAGS IN THE DAG ARE IDENTICAL.
184 	 */
185 
186 	char		 *name;		/* Debug only. */
187 	RF_DagNodeFlags_t flags;	/* See below. */
188 	RF_DagNode_t	 *dag_ptrs[RF_DAG_PTRCACHESIZE];
189 					/* Cache for performance. */
190 	RF_DagParam_t	  dag_params[RF_DAG_PARAMCACHESIZE];
191 					/* Cache for performance. */
192 };
193 
194 /*
195  * Bit values for flags field of RF_DagNode_t.
196  */
197 #define	RF_DAGNODE_FLAG_NONE	0x00
198 #define	RF_DAGNODE_FLAG_YIELD	0x01	/*
199 					 * In the kernel, yield the processor
200 					 * before firing this node.
201 					 */
202 
203 /*
204  * rf_enable	   - DAG ready for normal execution, no errors encountered.
205  * rf_rollForward  - DAG encountered an error after commit point, rolling
206  *		     forward.
207  * rf_rollBackward - DAG encountered an error prior to commit point, rolling
208  *		     backward.
209  */
210 typedef enum RF_DagStatus_e {
211 	rf_enable,
212 	rf_rollForward,
213 	rf_rollBackward
214 } RF_DagStatus_t;
215 
216 #define	RF_MAX_HDR_SUCC		 1
217 
218 #define	RF_MAXCHUNKS		10
219 
220 struct RF_DagHeader_s {
221 	RF_DagStatus_t	  status;		/* Status of this DAG. */
222 	int		  numSuccedents;	/*
223 						 * DAG may be a tree,
224 						 * i.e. may have > 1 root.
225 						 */
226 	int		  numCommitNodes;	/*
227 						 * Number of commit nodes
228 						 * in graph.
229 						 */
230 	int		  numCommits;		/*
231 						 * Number of commit nodes
232 						 * that have been fired.
233 						 */
234 	RF_DagNode_t	 *succedents[RF_MAX_HDR_SUCC];	/*
235 							 * Array of succedents,
236 							 * size numSuccedents.
237 							 */
238 	RF_DagHeader_t	 *next;			/*
239 						 * Ptr to allow a list
240 						 * of dags.
241 						 */
242 	RF_AllocListElem_t *allocList;		/*
243 						 * Ptr to list of ptrs
244 						 * to be freed prior to
245 						 * freeing DAG.
246 						 */
247 	RF_AccessStripeMapHeader_t *asmList;	/*
248 						 * List of access stripe maps
249 						 * to be freed.
250 						 */
251 	int		  nodeNum;		/*
252 						 * Used by PrintDAG for
253 						 * debug only.
254 						 */
255 	int		  numNodesCompleted;
256 	RF_AccTraceEntry_t *tracerec;		/* Perf mon only. */
257 
258 	void		(*cbFunc) (void *);	/*
259 						 * Function to call when
260 						 * the dag completes.
261 						 */
262 	void		 *cbArg;		/* Argument for cbFunc. */
263 	char		 *creator;		/*
264 						 * Name of function used
265 						 * to create this dag.
266 						 */
267 
268 	RF_Raid_t	 *raidPtr;		/*
269 						 * The descriptor for the
270 						 * RAID device this DAG
271 						 * is for.
272 						 */
273 	void		 *bp;			/*
274 						 * The bp for this I/O passed
275 						 * down from the file system.
276 						 * ignored outside kernel.
277 						 */
278 
279 	RF_ChunkDesc_t	 *memChunk[RF_MAXCHUNKS]; /*
280 						 * Experimental- Chunks of
281 						 * memory to be retained upon
282 						 * DAG free for re-use.
283 						 */
284 	int		  chunkIndex;		/*
285 						 * The idea is to avoid calls
286 						 * to alloc and free.
287 						 */
288 
289 	RF_ChunkDesc_t	**xtraMemChunk;		/*
290 						 * Escape hatch that allows
291 						 * SelectAlgorithm to merge
292 						 * memChunks from several dags.
293 						 */
294 	int		  xtraChunkIndex;	/*
295 						 * Number of ptrs to valid
296 						 * chunks.
297 						 */
298 	int		  xtraChunkCnt;		/*
299 						 * Number of ptrs to chunks
300 						 * allocated.
301 						 */
302 };
303 
304 struct RF_DagList_s {
305 	/* Common info for a list of dags that will be fired sequentially. */
306 	int		 numDags;	/* Number of dags in the list. */
307 	int		 numDagsFired;	/*
308 					 * Number of dags in list that
309 					 * have initiated execution.
310 					 */
311 	int		 numDagsDone;	/*
312 					 * Number of dags in list that
313 					 * have completed execution.
314 					 */
315 	RF_DagHeader_t	*dags;		/* List of dags. */
316 	RF_RaidAccessDesc_t *desc;	/* Ptr to descriptor for this access. */
317 	RF_AccTraceEntry_t tracerec;	/*
318 					 * Perf mon info for dags (not user
319 					 * info).
320 					 */
321 };
322 
323 /* Reset a node so that it can be fired again. */
324 #define	RF_ResetNode(_n_)	do {					\
325 	(_n_)->status = rf_wait;					\
326 	(_n_)->numAntDone = 0;						\
327 	(_n_)->numSuccFired = 0;					\
328 	(_n_)->numSuccDone = 0;						\
329 	(_n_)->next = NULL;						\
330 } while (0)
331 
332 #define	RF_ResetDagHeader(_h_)	do {					\
333 	(_h_)->numNodesCompleted = 0;					\
334 	(_h_)->numCommits = 0;						\
335 	(_h_)->status = rf_enable;					\
336 } while (0)
337 
338 /* Convenience macro for declaring a create dag function. */
339 #define	RF_CREATE_DAG_FUNC_DECL(_name_)					\
340 void _name_ (RF_Raid_t *, RF_AccessStripeMap_t *, RF_DagHeader_t *,	\
341     void *, RF_RaidAccessFlags_t, RF_AllocListElem_t *);		\
342 void _name_ (								\
343 	RF_Raid_t		*raidPtr,				\
344 	RF_AccessStripeMap_t	*asmap,					\
345 	RF_DagHeader_t		*dag_h,					\
346 	void			*bp,					\
347 	RF_RaidAccessFlags_t	 flags,					\
348 	RF_AllocListElem_t	*allocList				\
349 )
350 
351 #endif	/* !_RF__RF_DAG_H_ */
352