[BACK]Return to rf_psstatus.c CVS log [TXT][DIR] Up to [local] / sys / dev / raidframe

Annotation of sys/dev/raidframe/rf_psstatus.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: rf_psstatus.c,v 1.6 2002/12/16 07:01:04 tdeval Exp $  */
        !             2: /*     $NetBSD: rf_psstatus.c,v 1.5 2000/01/08 22:57:31 oster Exp $    */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1995 Carnegie-Mellon University.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Author: Mark Holland
        !             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: /*****************************************************************************
        !            32:  *
        !            33:  * psstatus.c
        !            34:  *
        !            35:  * The reconstruction code maintains a bunch of status related to the parity
        !            36:  * stripes that are currently under reconstruction. This header file defines
        !            37:  * the status structures.
        !            38:  *
        !            39:  *****************************************************************************/
        !            40:
        !            41: #include "rf_types.h"
        !            42: #include "rf_raid.h"
        !            43: #include "rf_general.h"
        !            44: #include "rf_debugprint.h"
        !            45: #include "rf_freelist.h"
        !            46: #include "rf_psstatus.h"
        !            47: #include "rf_shutdown.h"
        !            48:
        !            49: #define        Dprintf1(s,a)                                                   \
        !            50: do {                                                                   \
        !            51:        if (rf_pssDebug)                                                \
        !            52:                rf_debug_printf(s,                                      \
        !            53:                    (void *)((unsigned long)a),                         \
        !            54:                    NULL, NULL, NULL, NULL, NULL, NULL, NULL);          \
        !            55: } while(0)
        !            56: #define        Dprintf2(s,a,b)                                                 \
        !            57: do {                                                                   \
        !            58:        if (rf_pssDebug)                                                \
        !            59:                rf_debug_printf(s,                                      \
        !            60:                    (void *)((unsigned long)a),                         \
        !            61:                    (void *)((unsigned long)b),                         \
        !            62:                    NULL, NULL, NULL, NULL, NULL, NULL);                \
        !            63: } while(0)
        !            64: #define        Dprintf3(s,a,b,c)                                               \
        !            65: do {                                                                   \
        !            66:        if (rf_pssDebug)                                                \
        !            67:                rf_debug_printf(s,                                      \
        !            68:                    (void *)((unsigned long)a),                         \
        !            69:                    (void *)((unsigned long)b),                         \
        !            70:                    (void *)((unsigned long)c),                         \
        !            71:                    NULL, NULL, NULL, NULL, NULL);                      \
        !            72: } while(0)
        !            73:
        !            74: void rf_RealPrintPSStatusTable(RF_Raid_t *, RF_PSStatusHeader_t *);
        !            75:
        !            76: #define        RF_MAX_FREE_PSS         32
        !            77: #define        RF_PSS_INC               8
        !            78: #define        RF_PSS_INITIAL           4
        !            79:
        !            80: int  rf_init_pss(RF_ReconParityStripeStatus_t *, RF_Raid_t *);
        !            81: void rf_clean_pss(RF_ReconParityStripeStatus_t *, RF_Raid_t *);
        !            82: void rf_ShutdownPSStatus(void *);
        !            83:
        !            84: int
        !            85: rf_init_pss(RF_ReconParityStripeStatus_t *p, RF_Raid_t *raidPtr)
        !            86: {
        !            87:        RF_Calloc(p->issued, raidPtr->numCol, sizeof(char), (char *));
        !            88:        if (p->issued == NULL)
        !            89:                return (ENOMEM);
        !            90:        return (0);
        !            91: }
        !            92:
        !            93: void
        !            94: rf_clean_pss(RF_ReconParityStripeStatus_t *p, RF_Raid_t *raidPtr)
        !            95: {
        !            96:        RF_Free(p->issued, raidPtr->numCol * sizeof(char));
        !            97: }
        !            98:
        !            99: void
        !           100: rf_ShutdownPSStatus(void *arg)
        !           101: {
        !           102:        RF_Raid_t *raidPtr = (RF_Raid_t *) arg;
        !           103:
        !           104:        RF_FREELIST_DESTROY_CLEAN_ARG(raidPtr->pss_freelist, next,
        !           105:            (RF_ReconParityStripeStatus_t *), rf_clean_pss, raidPtr);
        !           106: }
        !           107:
        !           108: int
        !           109: rf_ConfigurePSStatus(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
        !           110:     RF_Config_t *cfgPtr)
        !           111: {
        !           112:        int rc;
        !           113:
        !           114:        raidPtr->pssTableSize = RF_PSS_DEFAULT_TABLESIZE;
        !           115:        RF_FREELIST_CREATE(raidPtr->pss_freelist, RF_MAX_FREE_PSS, RF_PSS_INC,
        !           116:            sizeof(RF_ReconParityStripeStatus_t));
        !           117:        if (raidPtr->pss_freelist == NULL)
        !           118:                return (ENOMEM);
        !           119:        rc = rf_ShutdownCreate(listp, rf_ShutdownPSStatus, raidPtr);
        !           120:        if (rc) {
        !           121:                RF_ERRORMSG3("Unable to add to shutdown list file %s line %d"
        !           122:                             " rc=%d.\n", __FILE__, __LINE__, rc);
        !           123:                rf_ShutdownPSStatus(raidPtr);
        !           124:                return (rc);
        !           125:        }
        !           126:        RF_FREELIST_PRIME_INIT_ARG(raidPtr->pss_freelist, RF_PSS_INITIAL, next,
        !           127:            (RF_ReconParityStripeStatus_t *), rf_init_pss, raidPtr);
        !           128:        return (0);
        !           129: }
        !           130:
        !           131:
        !           132: /*****************************************************************************
        !           133:  * Sets up the pss table.
        !           134:  * We pre-allocate a bunch of entries to avoid as much as possible having to
        !           135:  * malloc up hash chain entries.
        !           136:  *****************************************************************************/
        !           137: RF_PSStatusHeader_t *
        !           138: rf_MakeParityStripeStatusTable(RF_Raid_t *raidPtr)
        !           139: {
        !           140:        RF_PSStatusHeader_t *pssTable;
        !           141:        int i, j, rc;
        !           142:
        !           143:        RF_Calloc(pssTable, raidPtr->pssTableSize, sizeof(RF_PSStatusHeader_t),
        !           144:            (RF_PSStatusHeader_t *));
        !           145:        for (i = 0; i < raidPtr->pssTableSize; i++) {
        !           146:                rc = rf_mutex_init(&pssTable[i].mutex);
        !           147:                if (rc) {
        !           148:                        RF_ERRORMSG3("Unable to init mutex file %s line %d"
        !           149:                                     " rc=%d.\n", __FILE__, __LINE__, rc);
        !           150:                        /* Fail and deallocate. */
        !           151:                        for (j = 0; j < i; j++) {
        !           152:                                rf_mutex_destroy(&pssTable[i].mutex);
        !           153:                        }
        !           154:                        RF_Free(pssTable, raidPtr->pssTableSize *
        !           155:                            sizeof(RF_PSStatusHeader_t));
        !           156:                        return (NULL);
        !           157:                }
        !           158:        }
        !           159:        return (pssTable);
        !           160: }
        !           161:
        !           162: void
        !           163: rf_FreeParityStripeStatusTable(RF_Raid_t *raidPtr,
        !           164:     RF_PSStatusHeader_t *pssTable)
        !           165: {
        !           166:        int i;
        !           167:
        !           168:        if (rf_pssDebug)
        !           169:                rf_RealPrintPSStatusTable(raidPtr, pssTable);
        !           170:        for (i = 0; i < raidPtr->pssTableSize; i++) {
        !           171:                if (pssTable[i].chain) {
        !           172:                        printf("ERROR: pss hash chain not null at recon"
        !           173:                               " shutdown.\n");
        !           174:                }
        !           175:                rf_mutex_destroy(&pssTable[i].mutex);
        !           176:        }
        !           177:        RF_Free(pssTable, raidPtr->pssTableSize * sizeof(RF_PSStatusHeader_t));
        !           178: }
        !           179:
        !           180:
        !           181: /*
        !           182:  * Looks up the status structure for a parity stripe.
        !           183:  * If the create_flag is on, returns the status structure, creating it if
        !           184:  * it doesn't exist. Otherwise returns NULL if the status structure does
        !           185:  * not exist already.
        !           186:  *
        !           187:  * The flags tell whether or not to create it if it doesn't exist + what
        !           188:  * flags to set initially.
        !           189:  *
        !           190:  * ASSUMES THE PSS DESCRIPTOR IS LOCKED UPON ENTRY.
        !           191:  */
        !           192: RF_ReconParityStripeStatus_t *
        !           193: rf_LookupRUStatus(RF_Raid_t *raidPtr, RF_PSStatusHeader_t *pssTable,
        !           194:     RF_StripeNum_t psID, RF_ReconUnitNum_t which_ru, RF_PSSFlags_t flags,
        !           195:     int *created)
        !           196: {
        !           197:        RF_PSStatusHeader_t *hdr = &pssTable[RF_HASH_PSID(raidPtr, psID)];
        !           198:        RF_ReconParityStripeStatus_t *p, *pssPtr = hdr->chain;
        !           199:
        !           200:        *created = 0;
        !           201:        for (p = pssPtr; p; p = p->next) {
        !           202:                if (p->parityStripeID == psID && p->which_ru == which_ru)
        !           203:                        break;
        !           204:        }
        !           205:
        !           206:        if (!p && (flags & RF_PSS_CREATE)) {
        !           207:                Dprintf2("PSS: creating pss for psid %ld ru %d.\n",
        !           208:                    psID, which_ru);
        !           209:                p = rf_AllocPSStatus(raidPtr);
        !           210:                p->next = hdr->chain;
        !           211:                hdr->chain = p;
        !           212:
        !           213:                p->parityStripeID = psID;
        !           214:                p->which_ru = which_ru;
        !           215:                p->flags = flags;
        !           216:                p->rbuf = NULL;
        !           217:                p->writeRbuf = NULL;
        !           218:                p->xorBufCount = 0;
        !           219:                p->blockCount = 0;
        !           220:                p->procWaitList = NULL;
        !           221:                p->blockWaitList = NULL;
        !           222:                p->bufWaitList = NULL;
        !           223:                *created = 1;
        !           224:        } else
        !           225:                if (p) {
        !           226:                        /*
        !           227:                         * We didn't create, but we want to specify
        !           228:                         * some new status.
        !           229:                         */
        !           230:                        p->flags |= flags;      /*
        !           231:                                                 * Add in whatever flags we're
        !           232:                                                 * specifying.
        !           233:                                                 */
        !           234:                }
        !           235:        if (p && (flags & RF_PSS_RECON_BLOCKED)) {
        !           236:                /* If we're asking to block recon, bump the count. */
        !           237:                p->blockCount++;
        !           238:                Dprintf3("raid%d: Blocked recon on psid %ld. count now %d.\n",
        !           239:                         raidPtr->raidid, psID, p->blockCount);
        !           240:        }
        !           241:        return (p);
        !           242: }
        !           243:
        !           244:
        !           245: /*
        !           246:  * Deletes an entry from the parity stripe status table. Typically used
        !           247:  * when an entry has been allocated solely to block reconstruction, and
        !           248:  * no recon was requested while recon was blocked. Assumes the hash
        !           249:  * chain is ALREADY LOCKED.
        !           250:  */
        !           251: void
        !           252: rf_PSStatusDelete(RF_Raid_t *raidPtr, RF_PSStatusHeader_t *pssTable,
        !           253:     RF_ReconParityStripeStatus_t *pssPtr)
        !           254: {
        !           255:        RF_PSStatusHeader_t *hdr =
        !           256:            &(pssTable[RF_HASH_PSID(raidPtr, pssPtr->parityStripeID)]);
        !           257:        RF_ReconParityStripeStatus_t *p = hdr->chain, *pt = NULL;
        !           258:
        !           259:        while (p) {
        !           260:                if (p == pssPtr) {
        !           261:                        if (pt)
        !           262:                                pt->next = p->next;
        !           263:                        else
        !           264:                                hdr->chain = p->next;
        !           265:                        p->next = NULL;
        !           266:                        rf_FreePSStatus(raidPtr, p);
        !           267:                        return;
        !           268:                }
        !           269:                pt = p;
        !           270:                p = p->next;
        !           271:        }
        !           272:        RF_ASSERT(0);           /* We must find it here. */
        !           273: }
        !           274:
        !           275:
        !           276: /*
        !           277:  * Deletes an entry from the ps status table after reconstruction has
        !           278:  * completed.
        !           279:  */
        !           280: void
        !           281: rf_RemoveFromActiveReconTable(RF_Raid_t *raidPtr, RF_RowCol_t row,
        !           282:     RF_StripeNum_t psid, RF_ReconUnitNum_t which_ru)
        !           283: {
        !           284:        RF_PSStatusHeader_t *hdr =
        !           285:            &(raidPtr->reconControl[row]
        !           286:             ->pssTable[RF_HASH_PSID(raidPtr, psid)]);
        !           287:        RF_ReconParityStripeStatus_t *p, *pt;
        !           288:        RF_CallbackDesc_t *cb, *cb1;
        !           289:
        !           290:        RF_LOCK_MUTEX(hdr->mutex);
        !           291:        for (pt = NULL, p = hdr->chain; p; pt = p, p = p->next) {
        !           292:                if ((p->parityStripeID == psid) && (p->which_ru == which_ru))
        !           293:                        break;
        !           294:        }
        !           295:        if (p == NULL) {
        !           296:                rf_PrintPSStatusTable(raidPtr, row);
        !           297:        }
        !           298:        RF_ASSERT(p);           /* It must be there. */
        !           299:
        !           300:        Dprintf2("PSS: deleting pss for psid %ld ru %d.\n", psid, which_ru);
        !           301:
        !           302:        /* Delete this entry from the hash chain. */
        !           303:        if (pt)
        !           304:                pt->next = p->next;
        !           305:        else
        !           306:                hdr->chain = p->next;
        !           307:        p->next = NULL;
        !           308:
        !           309:        RF_UNLOCK_MUTEX(hdr->mutex);
        !           310:
        !           311:        /* Wake-up anyone waiting on the parity stripe ID. */
        !           312:        cb = p->procWaitList;
        !           313:        p->procWaitList = NULL;
        !           314:        while (cb) {
        !           315:                Dprintf1("Waking up access waiting on parity stripe ID %ld.\n",
        !           316:                    p->parityStripeID);
        !           317:                cb1 = cb->next;
        !           318:                (cb->callbackFunc) (cb->callbackArg);
        !           319:
        !           320:                /*
        !           321:                 * THIS IS WHAT THE ORIGINAL CODE HAD... the extra 0 is bogus,
        !           322:                 * IMHO.
        !           323:                 */
        !           324:                /* (cb->callbackFunc)(cb->callbackArg, 0); */
        !           325:                rf_FreeCallbackDesc(cb);
        !           326:                cb = cb1;
        !           327:        }
        !           328:
        !           329:        rf_FreePSStatus(raidPtr, p);
        !           330: }
        !           331:
        !           332: RF_ReconParityStripeStatus_t *
        !           333: rf_AllocPSStatus(RF_Raid_t *raidPtr)
        !           334: {
        !           335:        RF_ReconParityStripeStatus_t *p;
        !           336:
        !           337:        RF_FREELIST_GET_INIT_ARG(raidPtr->pss_freelist, p, next,
        !           338:            (RF_ReconParityStripeStatus_t *), rf_init_pss, raidPtr);
        !           339:        if (p) {
        !           340:                bzero(p->issued, raidPtr->numCol);
        !           341:        }
        !           342:        p->next = NULL;
        !           343:        /*
        !           344:         * No need to initialize here b/c the only place we're called from is
        !           345:         * the above Lookup.
        !           346:         */
        !           347:        return (p);
        !           348: }
        !           349:
        !           350: void
        !           351: rf_FreePSStatus(RF_Raid_t *raidPtr, RF_ReconParityStripeStatus_t *p)
        !           352: {
        !           353:        RF_ASSERT(p->procWaitList == NULL);
        !           354:        RF_ASSERT(p->blockWaitList == NULL);
        !           355:        RF_ASSERT(p->bufWaitList == NULL);
        !           356:
        !           357:        RF_FREELIST_FREE_CLEAN_ARG(raidPtr->pss_freelist, p, next,
        !           358:            rf_clean_pss, raidPtr);
        !           359: }
        !           360:
        !           361: void
        !           362: rf_RealPrintPSStatusTable(RF_Raid_t *raidPtr, RF_PSStatusHeader_t *pssTable)
        !           363: {
        !           364:        int i, j, procsWaiting, blocksWaiting, bufsWaiting;
        !           365:        RF_ReconParityStripeStatus_t *p;
        !           366:        RF_CallbackDesc_t *cb;
        !           367:
        !           368:        printf("\nParity Stripe Status Table\n");
        !           369:        for (i = 0; i < raidPtr->pssTableSize; i++) {
        !           370:                for (p = pssTable[i].chain; p; p = p->next) {
        !           371:                        procsWaiting = blocksWaiting = bufsWaiting = 0;
        !           372:                        for (cb = p->procWaitList; cb; cb = cb->next)
        !           373:                                procsWaiting++;
        !           374:                        for (cb = p->blockWaitList; cb; cb = cb->next)
        !           375:                                blocksWaiting++;
        !           376:                        for (cb = p->bufWaitList; cb; cb = cb->next)
        !           377:                                bufsWaiting++;
        !           378:                        printf("PSID %ld RU %d : blockCount %d %d/%d/%d"
        !           379:                            " proc/block/buf waiting, issued ",
        !           380:                            (long) p->parityStripeID, p->which_ru,
        !           381:                            p->blockCount, procsWaiting, blocksWaiting,
        !           382:                            bufsWaiting);
        !           383:                        for (j = 0; j < raidPtr->numCol; j++)
        !           384:                                printf("%c", (p->issued[j]) ? '1' : '0');
        !           385:                        if (!p->flags)
        !           386:                                printf(" flags: (none)");
        !           387:                        else {
        !           388:                                if (p->flags & RF_PSS_UNDER_RECON)
        !           389:                                        printf(" under-recon");
        !           390:                                if (p->flags & RF_PSS_FORCED_ON_WRITE)
        !           391:                                        printf(" forced-w");
        !           392:                                if (p->flags & RF_PSS_FORCED_ON_READ)
        !           393:                                        printf(" forced-r");
        !           394:                                if (p->flags & RF_PSS_RECON_BLOCKED)
        !           395:                                        printf(" blocked");
        !           396:                                if (p->flags & RF_PSS_BUFFERWAIT)
        !           397:                                        printf(" bufwait");
        !           398:                        }
        !           399:                        printf("\n");
        !           400:                }
        !           401:        }
        !           402: }
        !           403:
        !           404: void
        !           405: rf_PrintPSStatusTable(RF_Raid_t *raidPtr, RF_RowCol_t row)
        !           406: {
        !           407:        RF_PSStatusHeader_t *pssTable = raidPtr->reconControl[row]->pssTable;
        !           408:        rf_RealPrintPSStatusTable(raidPtr, pssTable);
        !           409: }

CVSweb