[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

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