/* 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); } }
/* 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); }
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; }