1 | /* $NetBSD: rf_dag.h,v 1.19 2005/12/11 12:23:37 christos Exp $ */ |
2 | /* |
3 | * Copyright (c) 1995 Carnegie-Mellon University. |
4 | * All rights reserved. |
5 | * |
6 | * Author: William V. Courtright II, Mark Holland |
7 | * |
8 | * Permission to use, copy, modify and distribute this software and |
9 | * its documentation is hereby granted, provided that both the copyright |
10 | * notice and this permission notice appear in all copies of the |
11 | * software, derivative works or modified versions, and any portions |
12 | * thereof, and that both notices appear in supporting documentation. |
13 | * |
14 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" |
15 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND |
16 | * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. |
17 | * |
18 | * Carnegie Mellon requests users of this software to return to |
19 | * |
20 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU |
21 | * School of Computer Science |
22 | * Carnegie Mellon University |
23 | * Pittsburgh PA 15213-3890 |
24 | * |
25 | * any improvements or extensions that they make and grant Carnegie the |
26 | * rights to redistribute these changes. |
27 | */ |
28 | |
29 | /**************************************************************************** |
30 | * * |
31 | * dag.h -- header file for DAG-related data structures * |
32 | * * |
33 | ****************************************************************************/ |
34 | |
35 | #ifndef _RF__RF_DAG_H_ |
36 | #define _RF__RF_DAG_H_ |
37 | |
38 | #include <dev/raidframe/raidframevar.h> |
39 | |
40 | #include "rf_threadstuff.h" |
41 | #include "rf_alloclist.h" |
42 | #include "rf_stripelocks.h" |
43 | #include "rf_layout.h" |
44 | #include "rf_dagflags.h" |
45 | #include "rf_acctrace.h" |
46 | #include "rf_desc.h" |
47 | |
48 | #define RF_THREAD_CONTEXT 0 /* we were invoked from thread context */ |
49 | #define RF_INTR_CONTEXT 1 /* we were invoked from interrupt context */ |
50 | #define RF_MAX_ANTECEDENTS 20 /* max num of antecedents a node may posses */ |
51 | |
52 | #include <sys/buf.h> |
53 | |
54 | struct { /* structure for propagation of results */ |
55 | int ; /* to parameter # paramNum */ |
56 | RF_PropHeader_t *; /* linked list for multiple results/params */ |
57 | }; |
58 | |
59 | typedef enum RF_NodeStatus_e { |
60 | rf_wait, /* node is waiting to be executed */ |
61 | rf_fired, /* node is currently executing its do function */ |
62 | rf_good, /* node successfully completed execution of |
63 | * its do function */ |
64 | rf_bad, /* node failed to successfully execute its do |
65 | * function */ |
66 | rf_skipped, /* not used anymore, used to imply a node was |
67 | * not executed */ |
68 | rf_recover, /* node is currently executing its undo |
69 | * function */ |
70 | rf_panic, /* node failed to successfully execute its |
71 | * undo function */ |
72 | rf_undone /* node successfully executed its undo |
73 | * function */ |
74 | } RF_NodeStatus_t; |
75 | /* |
76 | * These were used to control skipping a node. |
77 | * Now, these are only used as comments. |
78 | */ |
79 | typedef enum RF_AntecedentType_e { |
80 | rf_trueData, |
81 | rf_antiData, |
82 | rf_outputData, |
83 | rf_control |
84 | } RF_AntecedentType_t; |
85 | #define RF_DAG_PTRCACHESIZE 40 |
86 | #define RF_DAG_PARAMCACHESIZE 12 |
87 | |
88 | typedef RF_uint8 RF_DagNodeFlags_t; |
89 | |
90 | struct RF_DagNode_s { |
91 | RF_NodeStatus_t status; /* current status of this node */ |
92 | int (*doFunc) (RF_DagNode_t *); /* normal function */ |
93 | int (*undoFunc) (RF_DagNode_t *); /* func to remove effect of |
94 | * doFunc */ |
95 | int (*wakeFunc) (RF_DagNode_t *, int status); /* func called when the |
96 | * node completes an I/O */ |
97 | int numParams; /* number of parameters required by *funcPtr */ |
98 | int numResults; /* number of results produced by *funcPtr */ |
99 | int numAntecedents; /* number of antecedents */ |
100 | int numAntDone; /* number of antecedents which have finished */ |
101 | int numSuccedents; /* number of succedents */ |
102 | int numSuccFired; /* incremented when a succedent is fired |
103 | * during forward execution */ |
104 | int numSuccDone; /* incremented when a succedent finishes |
105 | * during rollBackward */ |
106 | int commitNode; /* boolean flag - if true, this is a commit |
107 | * node */ |
108 | RF_DagNode_t **succedents; /* succedents, array size |
109 | * numSuccedents */ |
110 | RF_DagNode_t **antecedents; /* antecedents, array size |
111 | * numAntecedents */ |
112 | RF_AntecedentType_t antType[RF_MAX_ANTECEDENTS]; /* type of each |
113 | * antecedent */ |
114 | void **results; /* array of results produced by *funcPtr */ |
115 | RF_DagParam_t *params; /* array of parameters required by *funcPtr */ |
116 | RF_PropHeader_t **propList; /* propagation list, size |
117 | * numSuccedents */ |
118 | RF_DagHeader_t *dagHdr; /* ptr to head of dag containing this node */ |
119 | void *dagFuncData; /* dag execution func uses this for whatever |
120 | * it wants */ |
121 | RF_DagNode_t *next; /* next in terms of propagating results */ |
122 | RF_DagNode_t *list_next; /* next in the list of DAG nodes for this DAG */ |
123 | int nodeNum; /* used by PrintDAG for debug only */ |
124 | int visited; /* used to avoid re-visiting nodes on DAG |
125 | * walks */ |
126 | /* ANY CODE THAT USES THIS FIELD MUST MAINTAIN THE PROPERTY THAT AFTER |
127 | * IT FINISHES, ALL VISITED FLAGS IN THE DAG ARE IDENTICAL */ |
128 | const char *name; /* debug only */ |
129 | RF_DagNodeFlags_t flags;/* see below */ |
130 | RF_DagNode_t *big_dag_ptrs; /* used in cases where the cache below isn't big enough */ |
131 | RF_DagParam_t *big_dag_params; /* used when the cache below isn't big enough */ |
132 | RF_DagNode_t *dag_ptrs[RF_DAG_PTRCACHESIZE]; /* cache for performance */ |
133 | RF_DagParam_t dag_params[RF_DAG_PARAMCACHESIZE]; /* cache for performance */ |
134 | }; |
135 | /* |
136 | * Bit values for flags field of RF_DagNode_t |
137 | */ |
138 | #define RF_DAGNODE_FLAG_NONE 0x00 |
139 | #define RF_DAGNODE_FLAG_YIELD 0x01 /* in the kernel, yield the processor |
140 | * before firing this node */ |
141 | |
142 | /* enable - DAG ready for normal execution, no errors encountered |
143 | * rollForward - DAG encountered an error after commit point, rolling forward |
144 | * rollBackward - DAG encountered an error prior to commit point, rolling backward |
145 | */ |
146 | typedef enum RF_DagStatus_e { |
147 | rf_enable, |
148 | rf_rollForward, |
149 | rf_rollBackward |
150 | } RF_DagStatus_t; |
151 | #define RF_MAX_HDR_SUCC 1 |
152 | |
153 | struct { |
154 | RF_DagStatus_t ; /* status of this DAG */ |
155 | int ; /* DAG may be a tree, i.e. may have > 1 root */ |
156 | int ; /* number of commit nodes in graph */ |
157 | int ; /* number of commit nodes which have been |
158 | * fired */ |
159 | RF_DagNode_t *[RF_MAX_HDR_SUCC]; /* array of succedents, |
160 | * size numSuccedents */ |
161 | RF_DagHeader_t *; /* ptr to allow a list of dags */ |
162 | RF_AllocListElem_t *; /* ptr to list of ptrs to be freed |
163 | * prior to freeing DAG */ |
164 | RF_AccessStripeMapHeader_t *; /* list of access stripe maps |
165 | * to be freed */ |
166 | int ; /* used by PrintDAG for debug only */ |
167 | int ; |
168 | #if RF_ACC_TRACE > 0 |
169 | RF_AccTraceEntry_t *; /* perf mon only */ |
170 | #endif |
171 | void (*) (void *); /* function to call when the dag |
172 | * completes */ |
173 | void *; /* argument for cbFunc */ |
174 | const char *; /* name of function used to create this dag */ |
175 | RF_DagNode_t *; /* linked list of nodes used in this DAG */ |
176 | RF_PhysDiskAddr_t *; /* for PDAs that can't get |
177 | cleaned up any other way... */ |
178 | RF_Raid_t *; /* the descriptor for the RAID device this DAG |
179 | * is for */ |
180 | RF_RaidAccessDesc_t *; /* ptr to descriptor for this access */ |
181 | void *; /* the bp for this I/O passed down from the |
182 | * file system. ignored outside kernel */ |
183 | }; |
184 | |
185 | struct RF_DagList_s { |
186 | /* common info for a list of dags which will be fired sequentially */ |
187 | int numDags; /* number of dags in the list */ |
188 | int numDagsFired; /* number of dags in list which have initiated |
189 | * execution */ |
190 | int numDagsDone; /* number of dags in list which have completed |
191 | * execution */ |
192 | RF_DagHeader_t *dags; /* list of dags */ |
193 | RF_RaidAccessDesc_t *desc; /* ptr to descriptor for this access */ |
194 | RF_AccTraceEntry_t tracerec; /* perf mon info for dags (not user |
195 | * info) */ |
196 | struct RF_DagList_s *next; /* next DagList, if any */ |
197 | }; |
198 | |
199 | /* convience macro for declaring a create dag function */ |
200 | |
201 | #define RF_CREATE_DAG_FUNC_DECL(_name_) \ |
202 | void _name_ ( \ |
203 | RF_Raid_t *raidPtr, \ |
204 | RF_AccessStripeMap_t *asmap, \ |
205 | RF_DagHeader_t *dag_h, \ |
206 | void *bp, \ |
207 | RF_RaidAccessFlags_t flags, \ |
208 | RF_AllocListElem_t *allocList) |
209 | |
210 | #endif /* !_RF__RF_DAG_H_ */ |
211 | |