root/dev/raidframe/rf_states.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. StateName
  2. rf_ContinueRaidAccess
  3. rf_ContinueDagAccess
  4. rf_State_LastState
  5. rf_State_IncrAccessCount
  6. rf_State_DecrAccessCount
  7. rf_State_Quiesce
  8. rf_State_Map
  9. rf_State_Lock
  10. rf_State_CreateDAG
  11. rf_State_ExecuteDAG
  12. rf_State_ProcessDAG
  13. rf_State_Cleanup

    1 /*      $OpenBSD: rf_states.c,v 1.9 2002/12/16 07:01:05 tdeval Exp $    */
    2 /*      $NetBSD: rf_states.c,v 1.15 2000/10/20 02:24:45 oster Exp $     */
    3 
    4 /*
    5  * Copyright (c) 1995 Carnegie-Mellon University.
    6  * All rights reserved.
    7  *
    8  * Author: Mark Holland, William V. Courtright II, Robby Findler
    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 #include <sys/errno.h>
   32 
   33 #include "rf_archs.h"
   34 #include "rf_threadstuff.h"
   35 #include "rf_raid.h"
   36 #include "rf_dag.h"
   37 #include "rf_desc.h"
   38 #include "rf_aselect.h"
   39 #include "rf_general.h"
   40 #include "rf_states.h"
   41 #include "rf_dagutils.h"
   42 #include "rf_driver.h"
   43 #include "rf_engine.h"
   44 #include "rf_map.h"
   45 #include "rf_etimer.h"
   46 #include "rf_kintf.h"
   47 
   48 /*
   49  * Prototypes for some of the available states.
   50  *
   51  * States must:
   52  *
   53  *   - not block.
   54  *
   55  *   - either schedule rf_ContinueRaidAccess as a callback and return
   56  *     RF_TRUE, or complete all of their work and return RF_FALSE.
   57  *
   58  *   - increment desc->state when they have finished their work.
   59  */
   60 
   61 char *StateName(RF_AccessState_t);
   62 
   63 char *
   64 StateName(RF_AccessState_t state)
   65 {
   66         switch (state) {
   67                 case rf_QuiesceState:return "QuiesceState";
   68         case rf_MapState:
   69                 return "MapState";
   70         case rf_LockState:
   71                 return "LockState";
   72         case rf_CreateDAGState:
   73                 return "CreateDAGState";
   74         case rf_ExecuteDAGState:
   75                 return "ExecuteDAGState";
   76         case rf_ProcessDAGState:
   77                 return "ProcessDAGState";
   78         case rf_CleanupState:
   79                 return "CleanupState";
   80         case rf_LastState:
   81                 return "LastState";
   82         case rf_IncrAccessesCountState:
   83                 return "IncrAccessesCountState";
   84         case rf_DecrAccessesCountState:
   85                 return "DecrAccessesCountState";
   86         default:
   87                 return "!!! UnnamedState !!!";
   88         }
   89 }
   90 
   91 void
   92 rf_ContinueRaidAccess(RF_RaidAccessDesc_t *desc)
   93 {
   94         int suspended = RF_FALSE;
   95         int current_state_index = desc->state;
   96         RF_AccessState_t current_state = desc->states[current_state_index];
   97         int unit = desc->raidPtr->raidid;
   98 
   99         do {
  100                 current_state_index = desc->state;
  101                 current_state = desc->states[current_state_index];
  102 
  103                 switch (current_state) {
  104 
  105                 case rf_QuiesceState:
  106                         suspended = rf_State_Quiesce(desc);
  107                         break;
  108                 case rf_IncrAccessesCountState:
  109                         suspended = rf_State_IncrAccessCount(desc);
  110                         break;
  111                 case rf_MapState:
  112                         suspended = rf_State_Map(desc);
  113                         break;
  114                 case rf_LockState:
  115                         suspended = rf_State_Lock(desc);
  116                         break;
  117                 case rf_CreateDAGState:
  118                         suspended = rf_State_CreateDAG(desc);
  119                         break;
  120                 case rf_ExecuteDAGState:
  121                         suspended = rf_State_ExecuteDAG(desc);
  122                         break;
  123                 case rf_ProcessDAGState:
  124                         suspended = rf_State_ProcessDAG(desc);
  125                         break;
  126                 case rf_CleanupState:
  127                         suspended = rf_State_Cleanup(desc);
  128                         break;
  129                 case rf_DecrAccessesCountState:
  130                         suspended = rf_State_DecrAccessCount(desc);
  131                         break;
  132                 case rf_LastState:
  133                         suspended = rf_State_LastState(desc);
  134                         break;
  135                 }
  136 
  137                 /*
  138                  * After this point, we cannot dereference desc since desc may
  139                  * have been freed. desc is only freed in LastState, so if we
  140                  * reenter this function or loop back up, desc should be valid.
  141                  */
  142 
  143                 if (rf_printStatesDebug) {
  144                         printf("raid%d: State: %-24s StateIndex: %3i desc:"
  145                                " 0x%ld %s.\n", unit, StateName(current_state),
  146                                current_state_index, (long) desc, suspended ?
  147                                "callback scheduled" : "looping");
  148                 }
  149         } while (!suspended && current_state != rf_LastState);
  150 
  151         return;
  152 }
  153 
  154 
  155 void
  156 rf_ContinueDagAccess(RF_DagList_t *dagList)
  157 {
  158         RF_AccTraceEntry_t *tracerec = &(dagList->desc->tracerec);
  159         RF_RaidAccessDesc_t *desc;
  160         RF_DagHeader_t *dag_h;
  161         RF_Etimer_t timer;
  162         int i;
  163 
  164         desc = dagList->desc;
  165 
  166         timer = tracerec->timer;
  167         RF_ETIMER_STOP(timer);
  168         RF_ETIMER_EVAL(timer);
  169         tracerec->specific.user.exec_us = RF_ETIMER_VAL_US(timer);
  170         RF_ETIMER_START(tracerec->timer);
  171 
  172         /* Skip to dag which just finished. */
  173         dag_h = dagList->dags;
  174         for (i = 0; i < dagList->numDagsDone; i++) {
  175                 dag_h = dag_h->next;
  176         }
  177 
  178         /* Check to see if retry is required. */
  179         if (dag_h->status == rf_rollBackward) {
  180                 /*
  181                  * When a dag fails, mark desc status as bad and allow all
  182                  * other dags in the desc to execute to completion. Then,
  183                  * free all dags and start over.
  184                  */
  185                 desc->status = 1;       /* Bad status. */
  186                 {
  187                         printf("raid%d: DAG failure: %c addr 0x%lx (%ld)"
  188                                " nblk 0x%x (%d) buf 0x%lx.\n",
  189                                desc->raidPtr->raidid, desc->type,
  190                                (long) desc->raidAddress,
  191                                (long) desc->raidAddress,
  192                                (int) desc->numBlocks, (int) desc->numBlocks,
  193                                (unsigned long) (desc->bufPtr));
  194                 }
  195         }
  196         dagList->numDagsDone++;
  197         rf_ContinueRaidAccess(desc);
  198 }
  199 
  200 int
  201 rf_State_LastState(RF_RaidAccessDesc_t *desc)
  202 {
  203         void (*callbackFunc) (RF_CBParam_t) = desc->callbackFunc;
  204         RF_CBParam_t callbackArg;
  205 
  206         callbackArg.p = desc->callbackArg;
  207 
  208         /*
  209          * If this is not an async request, wake up the caller.
  210          */
  211         if (desc->async_flag == 0)
  212                 wakeup(desc->bp);
  213 
  214         /*
  215          * That's all the IO for this one... Unbusy the 'disk'.
  216          */
  217 
  218         rf_disk_unbusy(desc);
  219 
  220         /*
  221          * Wakeup any requests waiting to go.
  222          */
  223 
  224         RF_LOCK_MUTEX(((RF_Raid_t *) desc->raidPtr)->mutex);
  225         ((RF_Raid_t *) desc->raidPtr)->openings++;
  226         RF_UNLOCK_MUTEX(((RF_Raid_t *) desc->raidPtr)->mutex);
  227 
  228         /* Wake up any pending I/O. */
  229         raidstart(((RF_Raid_t *) desc->raidPtr));
  230 
  231         /* printf("%s: Calling biodone on 0x%x.\n", __func__, desc->bp); */
  232         splassert(IPL_BIO);
  233         biodone(desc->bp);      /* Access came through ioctl. */
  234 
  235         if (callbackFunc)
  236                 callbackFunc(callbackArg);
  237         rf_FreeRaidAccDesc(desc);
  238 
  239         return RF_FALSE;
  240 }
  241 
  242 int
  243 rf_State_IncrAccessCount(RF_RaidAccessDesc_t *desc)
  244 {
  245         RF_Raid_t *raidPtr;
  246 
  247         raidPtr = desc->raidPtr;
  248         /*
  249          * Bummer. We have to do this to be 100% safe w.r.t. the increment
  250          * below.
  251          */
  252         RF_LOCK_MUTEX(raidPtr->access_suspend_mutex);
  253         raidPtr->accs_in_flight++;      /* Used to detect quiescence. */
  254         RF_UNLOCK_MUTEX(raidPtr->access_suspend_mutex);
  255 
  256         desc->state++;
  257         return RF_FALSE;
  258 }
  259 
  260 int
  261 rf_State_DecrAccessCount(RF_RaidAccessDesc_t *desc)
  262 {
  263         RF_Raid_t *raidPtr;
  264 
  265         raidPtr = desc->raidPtr;
  266 
  267         RF_LOCK_MUTEX(raidPtr->access_suspend_mutex);
  268         raidPtr->accs_in_flight--;
  269         if (raidPtr->accesses_suspended && raidPtr->accs_in_flight == 0) {
  270                 rf_SignalQuiescenceLock(raidPtr, raidPtr->reconDesc);
  271         }
  272         rf_UpdateUserStats(raidPtr, RF_ETIMER_VAL_US(desc->timer),
  273             desc->numBlocks);
  274         RF_UNLOCK_MUTEX(raidPtr->access_suspend_mutex);
  275 
  276         desc->state++;
  277         return RF_FALSE;
  278 }
  279 
  280 int
  281 rf_State_Quiesce(RF_RaidAccessDesc_t *desc)
  282 {
  283         RF_AccTraceEntry_t *tracerec = &desc->tracerec;
  284         RF_Etimer_t timer;
  285         int suspended = RF_FALSE;
  286         RF_Raid_t *raidPtr;
  287 
  288         raidPtr = desc->raidPtr;
  289 
  290         RF_ETIMER_START(timer);
  291         RF_ETIMER_START(desc->timer);
  292 
  293         RF_LOCK_MUTEX(raidPtr->access_suspend_mutex);
  294         if (raidPtr->accesses_suspended) {
  295                 RF_CallbackDesc_t *cb;
  296                 cb = rf_AllocCallbackDesc();
  297                 /*
  298                  * XXX The following cast is quite bogus...
  299                  * rf_ContinueRaidAccess takes a (RF_RaidAccessDesc_t *)
  300                  * as an argument... GO
  301                  */
  302                 cb->callbackFunc = (void (*) (RF_CBParam_t))
  303                     rf_ContinueRaidAccess;
  304                 cb->callbackArg.p = (void *) desc;
  305                 cb->next = raidPtr->quiesce_wait_list;
  306                 raidPtr->quiesce_wait_list = cb;
  307                 suspended = RF_TRUE;
  308         }
  309         RF_UNLOCK_MUTEX(raidPtr->access_suspend_mutex);
  310 
  311         RF_ETIMER_STOP(timer);
  312         RF_ETIMER_EVAL(timer);
  313         tracerec->specific.user.suspend_ovhd_us += RF_ETIMER_VAL_US(timer);
  314 
  315         if (suspended && rf_quiesceDebug)
  316                 printf("Stalling access due to quiescence lock.\n");
  317 
  318         desc->state++;
  319         return suspended;
  320 }
  321 
  322 int
  323 rf_State_Map(RF_RaidAccessDesc_t *desc)
  324 {
  325         RF_Raid_t *raidPtr = desc->raidPtr;
  326         RF_AccTraceEntry_t *tracerec = &desc->tracerec;
  327         RF_Etimer_t timer;
  328 
  329         RF_ETIMER_START(timer);
  330 
  331         if (!(desc->asmap = rf_MapAccess(raidPtr, desc->raidAddress,
  332              desc->numBlocks, desc->bufPtr, RF_DONT_REMAP)))
  333                 RF_PANIC();
  334 
  335         RF_ETIMER_STOP(timer);
  336         RF_ETIMER_EVAL(timer);
  337         tracerec->specific.user.map_us = RF_ETIMER_VAL_US(timer);
  338 
  339         desc->state++;
  340         return RF_FALSE;
  341 }
  342 
  343 int
  344 rf_State_Lock(RF_RaidAccessDesc_t *desc)
  345 {
  346         RF_AccTraceEntry_t *tracerec = &desc->tracerec;
  347         RF_Raid_t *raidPtr = desc->raidPtr;
  348         RF_AccessStripeMapHeader_t *asmh = desc->asmap;
  349         RF_AccessStripeMap_t *asm_p;
  350         RF_Etimer_t timer;
  351         int suspended = RF_FALSE;
  352 
  353         RF_ETIMER_START(timer);
  354         if (!(raidPtr->Layout.map->flags & RF_NO_STRIPE_LOCKS)) {
  355                 RF_StripeNum_t lastStripeID = -1;
  356 
  357                 /* Acquire each lock that we don't already hold. */
  358                 for (asm_p = asmh->stripeMap; asm_p; asm_p = asm_p->next) {
  359                         RF_ASSERT(RF_IO_IS_R_OR_W(desc->type));
  360                         if (!rf_suppressLocksAndLargeWrites &&
  361                             asm_p->parityInfo &&
  362                             !(desc->flags & RF_DAG_SUPPRESS_LOCKS) &&
  363                             !(asm_p->flags & RF_ASM_FLAGS_LOCK_TRIED)) {
  364                                 asm_p->flags |= RF_ASM_FLAGS_LOCK_TRIED;
  365                                 /* Locks must be acquired hierarchically. */
  366                                 RF_ASSERT(asm_p->stripeID > lastStripeID);
  367                                 lastStripeID = asm_p->stripeID;
  368                                 /*
  369                                  * XXX The cast to (void (*)(RF_CBParam_t))
  370                                  * below is bogus !  GO
  371                                  */
  372                                 RF_INIT_LOCK_REQ_DESC(asm_p->lockReqDesc,
  373                                     desc->type, (void (*) (struct buf *))
  374                                      rf_ContinueRaidAccess, desc, asm_p,
  375                                     raidPtr->Layout.dataSectorsPerStripe);
  376                                 if (rf_AcquireStripeLock(raidPtr->lockTable,
  377                                      asm_p->stripeID, &asm_p->lockReqDesc)) {
  378                                         suspended = RF_TRUE;
  379                                         break;
  380                                 }
  381                         }
  382                         if (desc->type == RF_IO_TYPE_WRITE &&
  383                             raidPtr->status[asm_p->physInfo->row] ==
  384                             rf_rs_reconstructing) {
  385                                 if (!(asm_p->flags & RF_ASM_FLAGS_FORCE_TRIED))
  386                                 {
  387                                         int val;
  388 
  389                                         asm_p->flags |=
  390                                             RF_ASM_FLAGS_FORCE_TRIED;
  391                                         /*
  392                                          * XXX The cast below is quite
  393                                          * bogus !!! XXX  GO
  394                                          */
  395                                         val = rf_ForceOrBlockRecon(raidPtr,
  396                                             asm_p,
  397                                             (void (*) (RF_Raid_t *, void *))
  398                                              rf_ContinueRaidAccess, desc);
  399                                         if (val == 0) {
  400                                                 asm_p->flags |=
  401                                                     RF_ASM_FLAGS_RECON_BLOCKED;
  402                                         } else {
  403                                                 suspended = RF_TRUE;
  404                                                 break;
  405                                         }
  406                                 } else {
  407                                         if (rf_pssDebug) {
  408                                                 printf("raid%d: skipping"
  409                                                        " force/block because"
  410                                                        " already done, psid"
  411                                                        " %ld.\n",
  412                                                        desc->raidPtr->raidid,
  413                                                        (long) asm_p->stripeID);
  414                                         }
  415                                 }
  416                         } else {
  417                                 if (rf_pssDebug) {
  418                                         printf("raid%d: skipping force/block"
  419                                                " because not write or not"
  420                                                " under recon, psid %ld.\n",
  421                                                desc->raidPtr->raidid,
  422                                                (long) asm_p->stripeID);
  423                                 }
  424                         }
  425                 }
  426 
  427                 RF_ETIMER_STOP(timer);
  428                 RF_ETIMER_EVAL(timer);
  429                 tracerec->specific.user.lock_us += RF_ETIMER_VAL_US(timer);
  430 
  431                 if (suspended)
  432                         return (RF_TRUE);
  433         }
  434         desc->state++;
  435         return (RF_FALSE);
  436 }
  437 
  438 /*
  439  * The following three states create, execute, and post-process DAGs.
  440  * The error recovery unit is a single DAG.
  441  * By default, SelectAlgorithm creates an array of DAGs, one per parity stripe.
  442  * In some tricky cases, multiple dags per stripe are created.
  443  *   - DAGs within a parity stripe are executed sequentially (arbitrary order).
  444  *   - DAGs for distinct parity stripes are executed concurrently.
  445  *
  446  * Repeat until all DAGs complete successfully -or- DAG selection fails.
  447  *
  448  * while !done
  449  *   create dag(s) (SelectAlgorithm)
  450  *   if dag
  451  *     execute dag (DispatchDAG)
  452  *     if dag successful
  453  *       done (SUCCESS)
  454  *     else
  455  *       !done (RETRY - start over with new dags)
  456  *   else
  457  *     done (FAIL)
  458  */
  459 int
  460 rf_State_CreateDAG(RF_RaidAccessDesc_t *desc)
  461 {
  462         RF_AccTraceEntry_t *tracerec = &desc->tracerec;
  463         RF_Etimer_t timer;
  464         RF_DagHeader_t *dag_h;
  465         int i, selectStatus;
  466 
  467         /*
  468          * Generate a dag for the access, and fire it off. When the dag
  469          * completes, we'll get re-invoked in the next state.
  470          */
  471         RF_ETIMER_START(timer);
  472         /* SelectAlgorithm returns one or more dags. */
  473         selectStatus = rf_SelectAlgorithm(desc,
  474             desc->flags | RF_DAG_SUPPRESS_LOCKS);
  475         if (rf_printDAGsDebug)
  476                 for (i = 0; i < desc->numStripes; i++)
  477                         rf_PrintDAGList(desc->dagArray[i].dags);
  478         RF_ETIMER_STOP(timer);
  479         RF_ETIMER_EVAL(timer);
  480         /* Update time to create all dags. */
  481         tracerec->specific.user.dag_create_us = RF_ETIMER_VAL_US(timer);
  482 
  483         desc->status = 0;       /* Good status. */
  484 
  485         if (selectStatus) {
  486                 /* Failed to create a dag. */
  487                 /*
  488                  * This happens when there are too many faults or incomplete
  489                  * dag libraries.
  490                  */
  491                 printf("[Failed to create a DAG]\n");
  492                 RF_PANIC();
  493         } else {
  494                 /* Bind dags to desc. */
  495                 for (i = 0; i < desc->numStripes; i++) {
  496                         dag_h = desc->dagArray[i].dags;
  497                         while (dag_h) {
  498                                 dag_h->bp = (struct buf *) desc->bp;
  499                                 dag_h->tracerec = tracerec;
  500                                 dag_h = dag_h->next;
  501                         }
  502                 }
  503                 desc->flags |= RF_DAG_DISPATCH_RETURNED;
  504                 desc->state++;  /* Next state should be rf_State_ExecuteDAG. */
  505         }
  506         return RF_FALSE;
  507 }
  508 
  509 
  510 /*
  511  * The access has an array of dagLists, one dagList per parity stripe.
  512  * Fire the first DAG in each parity stripe (dagList).
  513  * DAGs within a stripe (dagList) must be executed sequentially.
  514  *  - This preserves atomic parity update.
  515  * DAGs for independents parity groups (stripes) are fired concurrently.
  516  */
  517 int
  518 rf_State_ExecuteDAG(RF_RaidAccessDesc_t *desc)
  519 {
  520         int i;
  521         RF_DagHeader_t *dag_h;
  522         RF_DagList_t *dagArray = desc->dagArray;
  523 
  524         /*
  525          * Next state is always rf_State_ProcessDAG. Important to do this
  526          * before firing the first dag (it may finish before we leave this
  527          * routine).
  528          */
  529         desc->state++;
  530 
  531         /*
  532          * Sweep dag array, a stripe at a time, firing the first dag in each
  533          * stripe.
  534          */
  535         for (i = 0; i < desc->numStripes; i++) {
  536                 RF_ASSERT(dagArray[i].numDags > 0);
  537                 RF_ASSERT(dagArray[i].numDagsDone == 0);
  538                 RF_ASSERT(dagArray[i].numDagsFired == 0);
  539                 RF_ETIMER_START(dagArray[i].tracerec.timer);
  540                 /* Fire first dag in this stripe. */
  541                 dag_h = dagArray[i].dags;
  542                 RF_ASSERT(dag_h);
  543                 dagArray[i].numDagsFired++;
  544                 /*
  545                  * XXX Yet another case where we pass in a conflicting
  546                  * function pointer :-(  XXX  GO
  547                  */
  548                 rf_DispatchDAG(dag_h, (void (*) (void *)) rf_ContinueDagAccess,
  549                     &dagArray[i]);
  550         }
  551 
  552         /*
  553          * The DAG will always call the callback, even if there was no
  554          * blocking, so we are always suspended in this state.
  555          */
  556         return RF_TRUE;
  557 }
  558 
  559 
  560 /*
  561  * rf_State_ProcessDAG is entered when a dag completes.
  562  * First, check that all DAGs in the access have completed.
  563  * If not, fire as many DAGs as possible.
  564  */
  565 int
  566 rf_State_ProcessDAG(RF_RaidAccessDesc_t *desc)
  567 {
  568         RF_AccessStripeMapHeader_t *asmh = desc->asmap;
  569         RF_Raid_t *raidPtr = desc->raidPtr;
  570         RF_DagHeader_t *dag_h;
  571         int i, j, done = RF_TRUE;
  572         RF_DagList_t *dagArray = desc->dagArray;
  573         RF_Etimer_t timer;
  574 
  575         /* Check to see if this is the last dag. */
  576         for (i = 0; i < desc->numStripes; i++)
  577                 if (dagArray[i].numDags != dagArray[i].numDagsDone)
  578                         done = RF_FALSE;
  579 
  580         if (done) {
  581                 if (desc->status) {
  582                         /* A dag failed, retry. */
  583                         RF_ETIMER_START(timer);
  584                         /* Free all dags. */
  585                         for (i = 0; i < desc->numStripes; i++) {
  586                                 rf_FreeDAG(desc->dagArray[i].dags);
  587                         }
  588                         rf_MarkFailuresInASMList(raidPtr, asmh);
  589                         /* Back up to rf_State_CreateDAG. */
  590                         desc->state = desc->state - 2;
  591                         return RF_FALSE;
  592                 } else {
  593                         /* Move on to rf_State_Cleanup. */
  594                         desc->state++;
  595                 }
  596                 return RF_FALSE;
  597         } else {
  598                 /* More dags to execute. */
  599                 /* See if any are ready to be fired. If so, fire them. */
  600                 /*
  601                  * Don't fire the initial dag in a list, it's fired in
  602                  * rf_State_ExecuteDAG.
  603                  */
  604                 for (i = 0; i < desc->numStripes; i++) {
  605                         if ((dagArray[i].numDagsDone < dagArray[i].numDags) &&
  606                             (dagArray[i].numDagsDone ==
  607                              dagArray[i].numDagsFired) &&
  608                             (dagArray[i].numDagsFired > 0)) {
  609                                 RF_ETIMER_START(dagArray[i].tracerec.timer);
  610                                 /* Fire next dag in this stripe. */
  611                                 /*
  612                                  * First, skip to next dag awaiting execution.
  613                                  */
  614                                 dag_h = dagArray[i].dags;
  615                                 for (j = 0; j < dagArray[i].numDagsDone; j++)
  616                                         dag_h = dag_h->next;
  617                                 dagArray[i].numDagsFired++;
  618                                 /*
  619                                  * XXX And again we pass a different function
  620                                  * pointer... GO
  621                                  */
  622                                 rf_DispatchDAG(dag_h, (void (*) (void *))
  623                                     rf_ContinueDagAccess, &dagArray[i]);
  624                         }
  625                 }
  626                 return RF_TRUE;
  627         }
  628 }
  629 
  630 /* Only make it this far if all dags complete successfully. */
  631 int
  632 rf_State_Cleanup(RF_RaidAccessDesc_t *desc)
  633 {
  634         RF_AccTraceEntry_t *tracerec = &desc->tracerec;
  635         RF_AccessStripeMapHeader_t *asmh = desc->asmap;
  636         RF_Raid_t *raidPtr = desc->raidPtr;
  637         RF_AccessStripeMap_t *asm_p;
  638         RF_DagHeader_t *dag_h;
  639         RF_Etimer_t timer;
  640         int i;
  641 
  642         desc->state++;
  643 
  644         timer = tracerec->timer;
  645         RF_ETIMER_STOP(timer);
  646         RF_ETIMER_EVAL(timer);
  647         tracerec->specific.user.dag_retry_us = RF_ETIMER_VAL_US(timer);
  648 
  649         /* The RAID I/O is complete. Clean up. */
  650         tracerec->specific.user.dag_retry_us = 0;
  651 
  652         RF_ETIMER_START(timer);
  653         if (desc->flags & RF_DAG_RETURN_DAG) {
  654                 /* Copy dags into paramDAG. */
  655                 *(desc->paramDAG) = desc->dagArray[0].dags;
  656                 dag_h = *(desc->paramDAG);
  657                 for (i = 1; i < desc->numStripes; i++) {
  658                         /* Concatenate dags from remaining stripes. */
  659                         RF_ASSERT(dag_h);
  660                         while (dag_h->next)
  661                                 dag_h = dag_h->next;
  662                         dag_h->next = desc->dagArray[i].dags;
  663                 }
  664         } else {
  665                 /* Free all dags. */
  666                 for (i = 0; i < desc->numStripes; i++) {
  667                         rf_FreeDAG(desc->dagArray[i].dags);
  668                 }
  669         }
  670 
  671         RF_ETIMER_STOP(timer);
  672         RF_ETIMER_EVAL(timer);
  673         tracerec->specific.user.cleanup_us = RF_ETIMER_VAL_US(timer);
  674 
  675         RF_ETIMER_START(timer);
  676         if (!(raidPtr->Layout.map->flags & RF_NO_STRIPE_LOCKS)) {
  677                 for (asm_p = asmh->stripeMap; asm_p; asm_p = asm_p->next) {
  678                         if (!rf_suppressLocksAndLargeWrites &&
  679                             asm_p->parityInfo &&
  680                             !(desc->flags & RF_DAG_SUPPRESS_LOCKS)) {
  681                                 RF_ASSERT_VALID_LOCKREQ(&asm_p->lockReqDesc);
  682                                 rf_ReleaseStripeLock(raidPtr->lockTable,
  683                                     asm_p->stripeID, &asm_p->lockReqDesc);
  684                         }
  685                         if (asm_p->flags & RF_ASM_FLAGS_RECON_BLOCKED) {
  686                                 rf_UnblockRecon(raidPtr, asm_p);
  687                         }
  688                 }
  689         }
  690         RF_ETIMER_STOP(timer);
  691         RF_ETIMER_EVAL(timer);
  692         tracerec->specific.user.lock_us += RF_ETIMER_VAL_US(timer);
  693 
  694         RF_ETIMER_START(timer);
  695         if (desc->flags & RF_DAG_RETURN_ASM)
  696                 *(desc->paramASM) = asmh;
  697         else
  698                 rf_FreeAccessStripeMap(asmh);
  699         RF_ETIMER_STOP(timer);
  700         RF_ETIMER_EVAL(timer);
  701         tracerec->specific.user.cleanup_us += RF_ETIMER_VAL_US(timer);
  702 
  703         RF_ETIMER_STOP(desc->timer);
  704         RF_ETIMER_EVAL(desc->timer);
  705 
  706         timer = desc->tracerec.tot_timer;
  707         RF_ETIMER_STOP(timer);
  708         RF_ETIMER_EVAL(timer);
  709         desc->tracerec.total_us = RF_ETIMER_VAL_US(timer);
  710 
  711         rf_LogTraceRec(raidPtr, tracerec);
  712 
  713         desc->flags |= RF_DAG_ACCESS_COMPLETE;
  714 
  715         return RF_FALSE;
  716 }

/* [<][>][^][v][top][bottom][index][help] */