int
rf_State_ExecuteDAG(RF_RaidAccessDesc_t *desc)
{
	int     i;
	RF_DagHeader_t *dag_h;
	RF_DagList_t *dagList;

	/* next state is always rf_State_ProcessDAG important to do
	 * this before firing the first dag (it may finish before we
	 * leave this routine) */
	desc->state++;

	/* sweep dag array, a stripe at a time, firing the first dag
	 * in each stripe */
	dagList = desc->dagList;
	for (i = 0; i < desc->numStripes; i++) {
		RF_ASSERT(dagList->numDags > 0);
		RF_ASSERT(dagList->numDagsDone == 0);
		RF_ASSERT(dagList->numDagsFired == 0);
#if RF_ACC_TRACE > 0
		RF_ETIMER_START(dagList->tracerec.timer);
#endif
		/* fire first dag in this stripe */
		dag_h = dagList->dags;
		RF_ASSERT(dag_h);
		dagList->numDagsFired++;
		rf_DispatchDAG(dag_h, (void (*) (void *)) rf_ContinueDagAccess, dagList);
		dagList = dagList->next;
	}

	/* the DAG will always call the callback, even if there was no
	 * blocking, so we are always suspended in this state */
	return RF_TRUE;
}
Beispiel #2
0
/*
 * The access has an array of dagLists, one dagList per parity stripe.
 * Fire the first DAG in each parity stripe (dagList).
 * DAGs within a stripe (dagList) must be executed sequentially.
 *  - This preserves atomic parity update.
 * DAGs for independents parity groups (stripes) are fired concurrently.
 */
int
rf_State_ExecuteDAG(RF_RaidAccessDesc_t *desc)
{
	int i;
	RF_DagHeader_t *dag_h;
	RF_DagList_t *dagArray = desc->dagArray;

	/*
	 * Next state is always rf_State_ProcessDAG. Important to do this
	 * before firing the first dag (it may finish before we leave this
	 * routine).
	 */
	desc->state++;

	/*
	 * Sweep dag array, a stripe at a time, firing the first dag in each
	 * stripe.
	 */
	for (i = 0; i < desc->numStripes; i++) {
		RF_ASSERT(dagArray[i].numDags > 0);
		RF_ASSERT(dagArray[i].numDagsDone == 0);
		RF_ASSERT(dagArray[i].numDagsFired == 0);
		RF_ETIMER_START(dagArray[i].tracerec.timer);
		/* Fire first dag in this stripe. */
		dag_h = dagArray[i].dags;
		RF_ASSERT(dag_h);
		dagArray[i].numDagsFired++;
		/*
		 * XXX Yet another case where we pass in a conflicting
		 * function pointer :-(  XXX  GO
		 */
		rf_DispatchDAG(dag_h, (void (*) (void *)) rf_ContinueDagAccess,
		    &dagArray[i]);
	}

	/*
	 * The DAG will always call the callback, even if there was no
	 * blocking, so we are always suspended in this state.
	 */
	return RF_TRUE;
}
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;
	}
}
Beispiel #4
0
/*
 * 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;
	}
}