/* only make it this far if all dags complete successfully */ int rf_State_Cleanup(RF_RaidAccessDesc_t *desc) { #if RF_ACC_TRACE > 0 RF_AccTraceEntry_t *tracerec = &desc->tracerec; RF_Etimer_t timer; #endif RF_AccessStripeMapHeader_t *asmh = desc->asmap; RF_Raid_t *raidPtr = desc->raidPtr; RF_AccessStripeMap_t *asm_p; RF_DagList_t *dagList; int i; desc->state++; #if RF_ACC_TRACE > 0 timer = tracerec->timer; RF_ETIMER_STOP(timer); RF_ETIMER_EVAL(timer); tracerec->specific.user.dag_retry_us = RF_ETIMER_VAL_US(timer); /* the RAID I/O is complete. Clean up. */ tracerec->specific.user.dag_retry_us = 0; RF_ETIMER_START(timer); #endif /* free all dags */ dagList = desc->dagList; for (i = 0; i < desc->numStripes; i++) { rf_FreeDAG(dagList->dags); dagList = dagList->next; } #if RF_ACC_TRACE > 0 RF_ETIMER_STOP(timer); RF_ETIMER_EVAL(timer); tracerec->specific.user.cleanup_us = RF_ETIMER_VAL_US(timer); RF_ETIMER_START(timer); #endif for (asm_p = asmh->stripeMap; asm_p; asm_p = asm_p->next) { if (!rf_suppressLocksAndLargeWrites && asm_p->parityInfo && !(desc->flags & RF_DAG_SUPPRESS_LOCKS)) { RF_ASSERT_VALID_LOCKREQ(&asm_p->lockReqDesc); rf_ReleaseStripeLock(raidPtr->lockTable, asm_p->stripeID, &asm_p->lockReqDesc); } if (asm_p->flags & RF_ASM_FLAGS_RECON_BLOCKED) { rf_UnblockRecon(raidPtr, asm_p); } } #if RF_ACC_TRACE > 0 RF_ETIMER_STOP(timer); RF_ETIMER_EVAL(timer); tracerec->specific.user.lock_us += RF_ETIMER_VAL_US(timer); RF_ETIMER_START(timer); #endif rf_FreeAccessStripeMap(asmh); #if RF_ACC_TRACE > 0 RF_ETIMER_STOP(timer); RF_ETIMER_EVAL(timer); tracerec->specific.user.cleanup_us += RF_ETIMER_VAL_US(timer); RF_ETIMER_STOP(desc->timer); RF_ETIMER_EVAL(desc->timer); timer = desc->tracerec.tot_timer; RF_ETIMER_STOP(timer); RF_ETIMER_EVAL(timer); desc->tracerec.total_us = RF_ETIMER_VAL_US(timer); rf_LogTraceRec(raidPtr, tracerec); #endif desc->flags |= RF_DAG_ACCESS_COMPLETE; return RF_FALSE; }
/* Only make it this far if all dags complete successfully. */ int rf_State_Cleanup(RF_RaidAccessDesc_t *desc) { RF_AccTraceEntry_t *tracerec = &desc->tracerec; RF_AccessStripeMapHeader_t *asmh = desc->asmap; RF_Raid_t *raidPtr = desc->raidPtr; RF_AccessStripeMap_t *asm_p; RF_DagHeader_t *dag_h; RF_Etimer_t timer; int i; desc->state++; timer = tracerec->timer; RF_ETIMER_STOP(timer); RF_ETIMER_EVAL(timer); tracerec->specific.user.dag_retry_us = RF_ETIMER_VAL_US(timer); /* The RAID I/O is complete. Clean up. */ tracerec->specific.user.dag_retry_us = 0; RF_ETIMER_START(timer); if (desc->flags & RF_DAG_RETURN_DAG) { /* Copy dags into paramDAG. */ *(desc->paramDAG) = desc->dagArray[0].dags; dag_h = *(desc->paramDAG); for (i = 1; i < desc->numStripes; i++) { /* Concatenate dags from remaining stripes. */ RF_ASSERT(dag_h); while (dag_h->next) dag_h = dag_h->next; dag_h->next = desc->dagArray[i].dags; } } else { /* Free all dags. */ for (i = 0; i < desc->numStripes; i++) { rf_FreeDAG(desc->dagArray[i].dags); } } RF_ETIMER_STOP(timer); RF_ETIMER_EVAL(timer); tracerec->specific.user.cleanup_us = RF_ETIMER_VAL_US(timer); RF_ETIMER_START(timer); if (!(raidPtr->Layout.map->flags & RF_NO_STRIPE_LOCKS)) { for (asm_p = asmh->stripeMap; asm_p; asm_p = asm_p->next) { if (!rf_suppressLocksAndLargeWrites && asm_p->parityInfo && !(desc->flags & RF_DAG_SUPPRESS_LOCKS)) { RF_ASSERT_VALID_LOCKREQ(&asm_p->lockReqDesc); rf_ReleaseStripeLock(raidPtr->lockTable, asm_p->stripeID, &asm_p->lockReqDesc); } if (asm_p->flags & RF_ASM_FLAGS_RECON_BLOCKED) { rf_UnblockRecon(raidPtr, asm_p); } } } RF_ETIMER_STOP(timer); RF_ETIMER_EVAL(timer); tracerec->specific.user.lock_us += RF_ETIMER_VAL_US(timer); RF_ETIMER_START(timer); if (desc->flags & RF_DAG_RETURN_ASM) *(desc->paramASM) = asmh; else rf_FreeAccessStripeMap(asmh); RF_ETIMER_STOP(timer); RF_ETIMER_EVAL(timer); tracerec->specific.user.cleanup_us += RF_ETIMER_VAL_US(timer); RF_ETIMER_STOP(desc->timer); RF_ETIMER_EVAL(desc->timer); timer = desc->tracerec.tot_timer; RF_ETIMER_STOP(timer); RF_ETIMER_EVAL(timer); desc->tracerec.total_us = RF_ETIMER_VAL_US(timer); rf_LogTraceRec(raidPtr, tracerec); desc->flags |= RF_DAG_ACCESS_COMPLETE; return RF_FALSE; }
int rf_State_ProcessDAG(RF_RaidAccessDesc_t *desc) { RF_AccessStripeMapHeader_t *asmh = desc->asmap; RF_Raid_t *raidPtr = desc->raidPtr; RF_DagHeader_t *dag_h; int i, j, done = RF_TRUE; RF_DagList_t *dagList, *temp; /* check to see if this is the last dag */ dagList = desc->dagList; for (i = 0; i < desc->numStripes; i++) { if (dagList->numDags != dagList->numDagsDone) done = RF_FALSE; dagList = dagList->next; } if (done) { if (desc->status) { /* a dag failed, retry */ /* free all dags */ dagList = desc->dagList; for (i = 0; i < desc->numStripes; i++) { rf_FreeDAG(dagList->dags); temp = dagList; dagList = dagList->next; rf_FreeDAGList(temp); } desc->dagList = NULL; rf_MarkFailuresInASMList(raidPtr, asmh); /* note the retry so that we'll bail in rf_State_CreateDAG() once we've retired the IO RF_RETRY_THRESHOLD times */ desc->numRetries++; /* back up to rf_State_CreateDAG */ desc->state = desc->state - 2; return RF_FALSE; } else { /* move on to rf_State_Cleanup */ desc->state++; } return RF_FALSE; } else { /* more dags to execute */ /* see if any are ready to be fired. if so, fire them */ /* don't fire the initial dag in a list, it's fired in * rf_State_ExecuteDAG */ dagList = desc->dagList; for (i = 0; i < desc->numStripes; i++) { if ((dagList->numDagsDone < dagList->numDags) && (dagList->numDagsDone == dagList->numDagsFired) && (dagList->numDagsFired > 0)) { #if RF_ACC_TRACE > 0 RF_ETIMER_START(dagList->tracerec.timer); #endif /* fire next dag in this stripe */ /* first, skip to next dag awaiting execution */ dag_h = dagList->dags; for (j = 0; j < dagList->numDagsDone; j++) dag_h = dag_h->next; dagList->numDagsFired++; rf_DispatchDAG(dag_h, (void (*) (void *)) rf_ContinueDagAccess, dagList); } dagList = dagList->next; } return RF_TRUE; } }
/* * rf_State_ProcessDAG is entered when a dag completes. * First, check that all DAGs in the access have completed. * If not, fire as many DAGs as possible. */ int rf_State_ProcessDAG(RF_RaidAccessDesc_t *desc) { RF_AccessStripeMapHeader_t *asmh = desc->asmap; RF_Raid_t *raidPtr = desc->raidPtr; RF_DagHeader_t *dag_h; int i, j, done = RF_TRUE; RF_DagList_t *dagArray = desc->dagArray; RF_Etimer_t timer; /* Check to see if this is the last dag. */ for (i = 0; i < desc->numStripes; i++) if (dagArray[i].numDags != dagArray[i].numDagsDone) done = RF_FALSE; if (done) { if (desc->status) { /* A dag failed, retry. */ RF_ETIMER_START(timer); /* Free all dags. */ for (i = 0; i < desc->numStripes; i++) { rf_FreeDAG(desc->dagArray[i].dags); } rf_MarkFailuresInASMList(raidPtr, asmh); /* Back up to rf_State_CreateDAG. */ desc->state = desc->state - 2; return RF_FALSE; } else { /* Move on to rf_State_Cleanup. */ desc->state++; } return RF_FALSE; } else { /* More dags to execute. */ /* See if any are ready to be fired. If so, fire them. */ /* * Don't fire the initial dag in a list, it's fired in * rf_State_ExecuteDAG. */ for (i = 0; i < desc->numStripes; i++) { if ((dagArray[i].numDagsDone < dagArray[i].numDags) && (dagArray[i].numDagsDone == dagArray[i].numDagsFired) && (dagArray[i].numDagsFired > 0)) { RF_ETIMER_START(dagArray[i].tracerec.timer); /* Fire next dag in this stripe. */ /* * First, skip to next dag awaiting execution. */ dag_h = dagArray[i].dags; for (j = 0; j < dagArray[i].numDagsDone; j++) dag_h = dag_h->next; dagArray[i].numDagsFired++; /* * XXX And again we pass a different function * pointer... GO */ rf_DispatchDAG(dag_h, (void (*) (void *)) rf_ContinueDagAccess, &dagArray[i]); } } return RF_TRUE; } }