| 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 | |