The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/raidframe/rf_psstatus.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: rf_psstatus.c,v 1.28 2004/03/18 16:54:54 oster Exp $   */
    2 /*
    3  * Copyright (c) 1995 Carnegie-Mellon University.
    4  * All rights reserved.
    5  *
    6  * Author: Mark Holland
    7  *
    8  * Permission to use, copy, modify and distribute this software and
    9  * its documentation is hereby granted, provided that both the copyright
   10  * notice and this permission notice appear in all copies of the
   11  * software, derivative works or modified versions, and any portions
   12  * thereof, and that both notices appear in supporting documentation.
   13  *
   14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
   16  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   17  *
   18  * Carnegie Mellon requests users of this software to return to
   19  *
   20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   21  *  School of Computer Science
   22  *  Carnegie Mellon University
   23  *  Pittsburgh PA 15213-3890
   24  *
   25  * any improvements or extensions that they make and grant Carnegie the
   26  * rights to redistribute these changes.
   27  */
   28 
   29 /*****************************************************************************
   30  *
   31  * psstatus.c
   32  *
   33  * The reconstruction code maintains a bunch of status related to the parity
   34  * stripes that are currently under reconstruction.  This header file defines
   35  * the status structures.
   36  *
   37  *****************************************************************************/
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: rf_psstatus.c,v 1.28 2004/03/18 16:54:54 oster Exp $");
   41 
   42 #include <dev/raidframe/raidframevar.h>
   43 
   44 #include "rf_raid.h"
   45 #include "rf_general.h"
   46 #include "rf_debugprint.h"
   47 #include "rf_psstatus.h"
   48 #include "rf_shutdown.h"
   49 
   50 #if RF_DEBUG_PSS
   51 #define Dprintf1(s,a)         if (rf_pssDebug) rf_debug_printf(s,(void *)((unsigned long)a),NULL,NULL,NULL,NULL,NULL,NULL,NULL)
   52 #define Dprintf2(s,a,b)       if (rf_pssDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),NULL,NULL,NULL,NULL,NULL,NULL)
   53 #define Dprintf3(s,a,b,c)     if (rf_pssDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),NULL,NULL,NULL,NULL,NULL)
   54 #else
   55 #define Dprintf1(s,a)
   56 #define Dprintf2(s,a,b)
   57 #define Dprintf3(s,a,b,c)
   58 #endif
   59 
   60 static void 
   61 RealPrintPSStatusTable(RF_Raid_t * raidPtr,
   62     RF_PSStatusHeader_t * pssTable);
   63 
   64 #define RF_MAX_FREE_PSS  32
   65 #define RF_MIN_FREE_PSS   8
   66 
   67 static void rf_ShutdownPSStatus(void *);
   68 
   69 static void 
   70 rf_ShutdownPSStatus(void *arg)
   71 {
   72 
   73         pool_destroy(&rf_pools.pss);
   74 }
   75 
   76 int 
   77 rf_ConfigurePSStatus(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
   78                      RF_Config_t *cfgPtr)
   79 {
   80 
   81         raidPtr->pssTableSize = RF_PSS_DEFAULT_TABLESIZE;
   82         rf_pool_init(&rf_pools.pss, sizeof(RF_ReconParityStripeStatus_t),
   83                      "raidpsspl", RF_MIN_FREE_PSS, RF_MAX_FREE_PSS);
   84         rf_ShutdownCreate(listp, rf_ShutdownPSStatus, raidPtr);
   85 
   86         return (0);
   87 }
   88 /*****************************************************************************************
   89  * sets up the pss table
   90  * We pre-allocate a bunch of entries to avoid as much as possible having to
   91  * malloc up hash chain entries.
   92  ****************************************************************************************/
   93 RF_PSStatusHeader_t *
   94 rf_MakeParityStripeStatusTable(RF_Raid_t *raidPtr)
   95 {
   96         RF_PSStatusHeader_t *pssTable;
   97         int     i;
   98         
   99         RF_Malloc(pssTable, 
  100                   raidPtr->pssTableSize * sizeof(RF_PSStatusHeader_t),
  101                   (RF_PSStatusHeader_t *));
  102         for (i = 0; i < raidPtr->pssTableSize; i++) {
  103                 rf_mutex_init(&pssTable[i].mutex);
  104         }
  105         return (pssTable);
  106 }
  107 
  108 void 
  109 rf_FreeParityStripeStatusTable(RF_Raid_t *raidPtr, 
  110                                RF_PSStatusHeader_t *pssTable)
  111 {
  112 #if RF_DEBUG_PSS
  113         int     i;
  114 
  115         if (rf_pssDebug)
  116                 RealPrintPSStatusTable(raidPtr, pssTable);
  117 
  118         for (i = 0; i < raidPtr->pssTableSize; i++) {
  119                 if (pssTable[i].chain) {
  120                         printf("ERROR: pss hash chain not null at recon shutdown\n");
  121                 }
  122         }
  123 #endif
  124         RF_Free(pssTable, raidPtr->pssTableSize * sizeof(RF_PSStatusHeader_t));
  125 }
  126 
  127 
  128 /* looks up the status structure for a parity stripe.
  129  * if the create_flag is on, uses (and returns) newpssPtr if
  130  * a parity status structure doesn't exist
  131  * otherwise returns NULL if the status structure does not exist
  132  *
  133  * ASSUMES THE PSS DESCRIPTOR IS LOCKED UPON ENTRY
  134  * 
  135  * flags - whether or not to use newpssPtr if the needed PSS
  136  *         doesn't exist and what flags to set it to initially
  137  */
  138 RF_ReconParityStripeStatus_t *
  139 rf_LookupRUStatus(RF_Raid_t *raidPtr, RF_PSStatusHeader_t *pssTable,
  140                   RF_StripeNum_t psID, RF_ReconUnitNum_t which_ru,
  141                   RF_PSSFlags_t flags, RF_ReconParityStripeStatus_t *newpssPtr)
  142 {
  143         RF_PSStatusHeader_t *hdr = &pssTable[RF_HASH_PSID(raidPtr, psID)];
  144         RF_ReconParityStripeStatus_t *p, *pssPtr = hdr->chain;
  145 
  146         for (p = pssPtr; p; p = p->next) {
  147                 if (p->parityStripeID == psID && p->which_ru == which_ru)
  148                         break;
  149         }
  150 
  151         if (!p && (flags & RF_PSS_CREATE)) {
  152                 p = newpssPtr;
  153                 p->next = hdr->chain;
  154                 hdr->chain = p;
  155 
  156                 p->parityStripeID = psID;
  157                 p->which_ru = which_ru;
  158                 p->flags = flags;
  159                 p->rbuf = NULL;
  160                 p->writeRbuf = NULL;
  161                 p->xorBufCount = 0;
  162                 p->blockCount = 0;
  163                 p->procWaitList = NULL;
  164                 p->blockWaitList = NULL;
  165                 p->bufWaitList = NULL;
  166         } else
  167                 if (p) {        /* we didn't create, but we want to specify
  168                                  * some new status */
  169                         p->flags |= flags;      /* add in whatever flags we're
  170                                                  * specifying */
  171                 }
  172         if (p && (flags & RF_PSS_RECON_BLOCKED)) {
  173                 p->blockCount++;/* if we're asking to block recon, bump the
  174                                  * count */
  175                 Dprintf3("raid%d: Blocked recon on psid %ld.  count now %d\n",
  176                          raidPtr->raidid, psID, p->blockCount);
  177         }
  178         return (p);
  179 }
  180 /* deletes an entry from the parity stripe status table.  typically used
  181  * when an entry has been allocated solely to block reconstruction, and
  182  * no recon was requested while recon was blocked.  Assumes the hash
  183  * chain is ALREADY LOCKED.
  184  */
  185 void 
  186 rf_PSStatusDelete(RF_Raid_t *raidPtr, RF_PSStatusHeader_t *pssTable, 
  187                   RF_ReconParityStripeStatus_t *pssPtr)
  188 {
  189         RF_PSStatusHeader_t *hdr = &(pssTable[RF_HASH_PSID(raidPtr, pssPtr->parityStripeID)]);
  190         RF_ReconParityStripeStatus_t *p = hdr->chain, *pt = NULL;
  191 
  192         while (p) {
  193                 if (p == pssPtr) {
  194                         if (pt)
  195                                 pt->next = p->next;
  196                         else
  197                                 hdr->chain = p->next;
  198                         p->next = NULL;
  199                         rf_FreePSStatus(raidPtr, p);
  200                         return;
  201                 }
  202                 pt = p;
  203                 p = p->next;
  204         }
  205         RF_ASSERT(0);           /* we must find it here */
  206 }
  207 /* deletes an entry from the ps status table after reconstruction has completed */
  208 void 
  209 rf_RemoveFromActiveReconTable(RF_Raid_t *raidPtr, RF_StripeNum_t psid, 
  210                               RF_ReconUnitNum_t which_ru)
  211 {
  212         RF_PSStatusHeader_t *hdr = &(raidPtr->reconControl->pssTable[RF_HASH_PSID(raidPtr, psid)]);
  213         RF_ReconParityStripeStatus_t *p, *pt;
  214         RF_CallbackDesc_t *cb, *cb1;
  215 
  216         RF_LOCK_MUTEX(hdr->mutex);
  217         while(hdr->lock) {
  218                 ltsleep(&hdr->lock, PRIBIO, "rf_racrecon", 0, &hdr->mutex);
  219         }
  220         hdr->lock = 1;
  221         RF_UNLOCK_MUTEX(hdr->mutex);    
  222         for (pt = NULL, p = hdr->chain; p; pt = p, p = p->next) {
  223                 if ((p->parityStripeID == psid) && (p->which_ru == which_ru))
  224                         break;
  225         }
  226         if (p == NULL) {
  227                 rf_PrintPSStatusTable(raidPtr);
  228         }
  229         RF_ASSERT(p);           /* it must be there */
  230 
  231         Dprintf2("PSS: deleting pss for psid %ld ru %d\n", psid, which_ru);
  232 
  233         /* delete this entry from the hash chain */
  234         if (pt)
  235                 pt->next = p->next;
  236         else
  237                 hdr->chain = p->next;
  238         p->next = NULL;
  239         
  240         RF_LOCK_MUTEX(hdr->mutex);
  241         hdr->lock = 0;
  242         RF_UNLOCK_MUTEX(hdr->mutex);
  243 
  244         /* wakup anyone waiting on the parity stripe ID */
  245         cb = p->procWaitList;
  246         p->procWaitList = NULL;
  247         while (cb) {
  248                 Dprintf1("Waking up access waiting on parity stripe ID %ld\n", p->parityStripeID);
  249                 cb1 = cb->next;
  250                 (cb->callbackFunc) (cb->callbackArg);
  251                 rf_FreeCallbackDesc(cb);
  252                 cb = cb1;
  253         }
  254 
  255         rf_FreePSStatus(raidPtr, p);
  256 }
  257 
  258 RF_ReconParityStripeStatus_t *
  259 rf_AllocPSStatus(RF_Raid_t *raidPtr)
  260 {
  261         RF_ReconParityStripeStatus_t *p;
  262 
  263         p = pool_get(&rf_pools.pss, PR_WAITOK);
  264         memset(p, 0, sizeof(RF_ReconParityStripeStatus_t));
  265         return (p);
  266 }
  267 
  268 void 
  269 rf_FreePSStatus(RF_Raid_t *raidPtr, RF_ReconParityStripeStatus_t *p)
  270 {
  271         RF_ASSERT(p->procWaitList == NULL);
  272         RF_ASSERT(p->blockWaitList == NULL);
  273         RF_ASSERT(p->bufWaitList == NULL);
  274 
  275         pool_put(&rf_pools.pss, p);
  276 }
  277 
  278 static void 
  279 RealPrintPSStatusTable(RF_Raid_t *raidPtr, RF_PSStatusHeader_t *pssTable)
  280 {
  281         int     i, j, procsWaiting, blocksWaiting, bufsWaiting;
  282         RF_ReconParityStripeStatus_t *p;
  283         RF_CallbackDesc_t *cb;
  284 
  285         printf("\nParity Stripe Status Table\n");
  286         for (i = 0; i < raidPtr->pssTableSize; i++) {
  287                 for (p = pssTable[i].chain; p; p = p->next) {
  288                         procsWaiting = blocksWaiting = bufsWaiting = 0;
  289                         for (cb = p->procWaitList; cb; cb = cb->next)
  290                                 procsWaiting++;
  291                         for (cb = p->blockWaitList; cb; cb = cb->next)
  292                                 blocksWaiting++;
  293                         for (cb = p->bufWaitList; cb; cb = cb->next)
  294                                 bufsWaiting++;
  295                         printf("PSID %ld RU %d : blockCount %d %d/%d/%d proc/block/buf waiting, issued ",
  296                             (long) p->parityStripeID, p->which_ru, p->blockCount, procsWaiting, blocksWaiting, bufsWaiting);
  297                         for (j = 0; j < raidPtr->numCol; j++)
  298                                 printf("%c", (p->issued[j]) ? '1' : '');
  299                         if (!p->flags)
  300                                 printf(" flags: (none)");
  301                         else {
  302                                 if (p->flags & RF_PSS_UNDER_RECON)
  303                                         printf(" under-recon");
  304                                 if (p->flags & RF_PSS_FORCED_ON_WRITE)
  305                                         printf(" forced-w");
  306                                 if (p->flags & RF_PSS_FORCED_ON_READ)
  307                                         printf(" forced-r");
  308                                 if (p->flags & RF_PSS_RECON_BLOCKED)
  309                                         printf(" blocked");
  310                                 if (p->flags & RF_PSS_BUFFERWAIT)
  311                                         printf(" bufwait");
  312                         }
  313                         printf("\n");
  314                 }
  315         }
  316 }
  317 
  318 void 
  319 rf_PrintPSStatusTable(RF_Raid_t *raidPtr)
  320 {
  321         RF_PSStatusHeader_t *pssTable = raidPtr->reconControl->pssTable;
  322         RealPrintPSStatusTable(raidPtr, pssTable);
  323 }

Cache object: c49a8ce4a4f0f3debc5d1304c8c51d69


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.