示例#1
0
/* wake up everyone waiting for quiescence to be released */
void
rf_ResumeNewRequests(RF_Raid_t *raidPtr)
{
	RF_CallbackDesc_t *t, *cb;

#if RF_DEBUG_QUIESCE
	if (rf_quiesceDebug)
		printf("raid%d: Resuming new requests\n", raidPtr->raidid);
#endif

	RF_LOCK_MUTEX(raidPtr->access_suspend_mutex);
	raidPtr->accesses_suspended--;
	if (raidPtr->accesses_suspended == 0)
		cb = raidPtr->quiesce_wait_list;
	else
		cb = NULL;
	raidPtr->quiesce_wait_list = NULL;
	RF_UNLOCK_MUTEX(raidPtr->access_suspend_mutex);

	while (cb) {
		t = cb;
		cb = cb->next;
		(t->callbackFunc) (t->callbackArg);
		rf_FreeCallbackDesc(t);
	}
}
示例#2
0
/* deletes an entry from the ps status table after reconstruction has completed */
void
rf_RemoveFromActiveReconTable(RF_Raid_t *raidPtr, RF_StripeNum_t psid,
			      RF_ReconUnitNum_t which_ru)
{
	RF_PSStatusHeader_t *hdr = &(raidPtr->reconControl->pssTable[RF_HASH_PSID(raidPtr, psid)]);
	RF_ReconParityStripeStatus_t *p, *pt;
	RF_CallbackDesc_t *cb, *cb1;

	RF_LOCK_MUTEX(hdr->mutex);
	while(hdr->lock) {
		ltsleep(&hdr->lock, PRIBIO, "rf_racrecon", 0, &hdr->mutex);
	}
	hdr->lock = 1;
	RF_UNLOCK_MUTEX(hdr->mutex);
	for (pt = NULL, p = hdr->chain; p; pt = p, p = p->next) {
		if ((p->parityStripeID == psid) && (p->which_ru == which_ru))
			break;
	}
	if (p == NULL) {
		rf_PrintPSStatusTable(raidPtr);
	}
	RF_ASSERT(p);		/* it must be there */

	Dprintf2("PSS: deleting pss for psid %ld ru %d\n", psid, which_ru);

	/* delete this entry from the hash chain */
	if (pt)
		pt->next = p->next;
	else
		hdr->chain = p->next;
	p->next = NULL;

	RF_LOCK_MUTEX(hdr->mutex);
	hdr->lock = 0;
	RF_UNLOCK_MUTEX(hdr->mutex);

	/* wakup anyone waiting on the parity stripe ID */
	cb = p->procWaitList;
	p->procWaitList = NULL;
	while (cb) {
		Dprintf1("Waking up access waiting on parity stripe ID %ld\n", p->parityStripeID);
		cb1 = cb->next;
		(cb->callbackFunc) (cb->callbackArg);
		rf_FreeCallbackDesc(cb);
		cb = cb1;
	}

	rf_FreePSStatus(raidPtr, p);
}
示例#3
0
int
rf_State_Quiesce(RF_RaidAccessDesc_t *desc)
{
#if RF_ACC_TRACE > 0
	RF_AccTraceEntry_t *tracerec = &desc->tracerec;
	RF_Etimer_t timer;
#endif
	RF_CallbackDesc_t *cb;
	RF_Raid_t *raidPtr;
	int     suspended = RF_FALSE;
	int need_cb, used_cb;

	raidPtr = desc->raidPtr;

#if RF_ACC_TRACE > 0
	RF_ETIMER_START(timer);
	RF_ETIMER_START(desc->timer);
#endif

	need_cb = 0;
	used_cb = 0;
	cb = NULL;

	rf_lock_mutex2(raidPtr->access_suspend_mutex);
	/* Do an initial check to see if we might need a callback structure */
	if (raidPtr->accesses_suspended) {
		need_cb = 1;
	}
	rf_unlock_mutex2(raidPtr->access_suspend_mutex);

	if (need_cb) {
		/* create a callback if we might need it...
		   and we likely do. */
		cb = rf_AllocCallbackDesc();
	}

	rf_lock_mutex2(raidPtr->access_suspend_mutex);
	if (raidPtr->accesses_suspended) {
		cb->callbackFunc = (void (*) (RF_CBParam_t)) rf_ContinueRaidAccess;
		cb->callbackArg.p = (void *) desc;
		cb->next = raidPtr->quiesce_wait_list;
		raidPtr->quiesce_wait_list = cb;
		suspended = RF_TRUE;
		used_cb = 1;
	}
	rf_unlock_mutex2(raidPtr->access_suspend_mutex);

	if ((need_cb == 1) && (used_cb == 0)) {
		rf_FreeCallbackDesc(cb);
	}

#if RF_ACC_TRACE > 0
	RF_ETIMER_STOP(timer);
	RF_ETIMER_EVAL(timer);
	tracerec->specific.user.suspend_ovhd_us += RF_ETIMER_VAL_US(timer);
#endif

#if RF_DEBUG_QUIESCE
	if (suspended && rf_quiesceDebug)
		printf("Stalling access due to quiescence lock\n");
#endif
	desc->state++;
	return suspended;
}