Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/raidframe For each RAID set, pre-allocate a number o...



details:   https://anonhg.NetBSD.org/src/rev/4076b9820e6e
branches:  trunk
changeset: 559550:4076b9820e6e
user:      oster <oster%NetBSD.org@localhost>
date:      Sat Mar 20 04:22:05 2004 +0000

description:
For each RAID set, pre-allocate a number of "emergency buffers" to be
used in the event that we can't malloc a buffer of the appropriate
size in the traditional way.  rf_AllocIOBuffer() and rf_FreeIOBuffer()
deal with allocating/freeing these structures.  These buffers are
stored in a list on the 'iobuf' list.  iobuf_count keeps track of how
many buffers are available, and numEmergencyBuffers is the effective
"high-water" mark for the freelist.  The buffers allocated by
rf_AllocIOBuffer() are stripe-unit sized, which is the maximum
size requested by any of the callers.

Add an iobufs entry to RF_DagHeader_s.  Use it for keeping track of
buffers that get allocated from the free-list.

Add a "generic list" pool (VoidPointerListElement Pool) for elements
used to maintain a list of allocated memory.  [It is somewhat less
than ideal to add another little pool to handle this...]

Teach rf_AllocBuffer() to use the new rf_AllocIOBuffer().  Modify
other Mallocs to use rf_AllocIOBuffer(), and to update dag_h->iobufs as
appropriate.

Update rf_FreeDAG() to handle cleanup of dag_h->iobufs.

While here, add some missing pool_destroy() calls for a number of pools.

With these changes, it should (in theory) be possible to swap on
RAID 5 sets again.  That said, I've not had any success there yet --
but the last issue I saw at least wasn't in RAIDframe. :-}

[There is room for this code to become a bit more consise, but I
wanted to do a checkpoint here with something known to work :) ]

diffstat:

 sys/dev/raidframe/rf_dag.h      |   4 +-
 sys/dev/raidframe/rf_dagdegwr.c |  12 +++-
 sys/dev/raidframe/rf_dagffwr.c  |  15 ++++--
 sys/dev/raidframe/rf_dagutils.c |  85 +++++++++++++++++++++++++++++++++++++---
 sys/dev/raidframe/rf_dagutils.h |   6 ++-
 sys/dev/raidframe/rf_driver.c   |  32 +++++++++++++-
 sys/dev/raidframe/rf_layout.h   |  10 ++++-
 sys/dev/raidframe/rf_map.c      |  32 ++++++++++++++-
 sys/dev/raidframe/rf_map.h      |   4 +-
 sys/dev/raidframe/rf_netbsd.h   |   7 ++-
 sys/dev/raidframe/rf_raid.h     |   6 ++-
 11 files changed, 186 insertions(+), 27 deletions(-)

diffs (truncated from 512 to 300 lines):

diff -r c18d1e8b5edb -r 4076b9820e6e sys/dev/raidframe/rf_dag.h
--- a/sys/dev/raidframe/rf_dag.h        Sat Mar 20 04:22:04 2004 +0000
+++ b/sys/dev/raidframe/rf_dag.h        Sat Mar 20 04:22:05 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rf_dag.h,v 1.14 2004/03/19 17:01:26 oster Exp $        */
+/*     $NetBSD: rf_dag.h,v 1.15 2004/03/20 04:22:05 oster Exp $        */
 /*
  * Copyright (c) 1995 Carnegie-Mellon University.
  * All rights reserved.
@@ -174,6 +174,8 @@
        RF_DagNode_t *nodes;    /* linked list of nodes used in this DAG */
        RF_PhysDiskAddr_t *pda_cleanup_list; /* for PDAs that can't get 
                                                cleaned up any other way... */
+       RF_VoidPointerListElem_t *iobufs; /* iobufs that need to be cleaned up at
+                                    the end of this IO */
        RF_Raid_t *raidPtr;     /* the descriptor for the RAID device this DAG
                                 * is for */
        void   *bp;             /* the bp for this I/O passed down from the
diff -r c18d1e8b5edb -r 4076b9820e6e sys/dev/raidframe/rf_dagdegwr.c
--- a/sys/dev/raidframe/rf_dagdegwr.c   Sat Mar 20 04:22:04 2004 +0000
+++ b/sys/dev/raidframe/rf_dagdegwr.c   Sat Mar 20 04:22:05 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rf_dagdegwr.c,v 1.19 2004/03/19 15:16:18 oster Exp $   */
+/*     $NetBSD: rf_dagdegwr.c,v 1.20 2004/03/20 04:22:05 oster Exp $   */
 /*
  * Copyright (c) 1995 Carnegie-Mellon University.
  * All rights reserved.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_dagdegwr.c,v 1.19 2004/03/19 15:16:18 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_dagdegwr.c,v 1.20 2004/03/20 04:22:05 oster Exp $");
 
 #include <dev/raidframe/raidframevar.h>
 
@@ -176,6 +176,7 @@
        RF_StripeNum_t parityStripeID;
        RF_PhysDiskAddr_t *failedPDA;
        RF_RaidLayout_t *layoutPtr;
+       RF_VoidPointerListElem_t *vple;
 
        layoutPtr = &(raidPtr->Layout);
        parityStripeID = rf_RaidAddressToParityStripeID(layoutPtr, asmap->raidAddress,
@@ -368,8 +369,11 @@
        parityPDA->numSector = failedPDA->numSector;
 
        if (!xorTargetBuf) {
-               RF_MallocAndAdd(xorTargetBuf,
-                   rf_RaidAddressToByte(raidPtr, failedPDA->numSector), (char *), allocList);
+               xorTargetBuf = rf_AllocIOBuffer(raidPtr, rf_RaidAddressToByte(raidPtr, failedPDA->numSector));
+               vple = rf_AllocVPListElem();
+               vple->p = xorTargetBuf;
+               vple->next = dag_h->iobufs;
+               dag_h->iobufs = vple;
        }
        /* init the Wnp node */
        rf_InitNode(wnpNode, rf_wait, RF_FALSE, rf_DiskWriteFunc, rf_DiskWriteUndoFunc,
diff -r c18d1e8b5edb -r 4076b9820e6e sys/dev/raidframe/rf_dagffwr.c
--- a/sys/dev/raidframe/rf_dagffwr.c    Sat Mar 20 04:22:04 2004 +0000
+++ b/sys/dev/raidframe/rf_dagffwr.c    Sat Mar 20 04:22:05 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rf_dagffwr.c,v 1.22 2004/03/18 16:40:05 oster Exp $    */
+/*     $NetBSD: rf_dagffwr.c,v 1.23 2004/03/20 04:22:05 oster Exp $    */
 /*
  * Copyright (c) 1995 Carnegie-Mellon University.
  * All rights reserved.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_dagffwr.c,v 1.22 2004/03/18 16:40:05 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_dagffwr.c,v 1.23 2004/03/20 04:22:05 oster Exp $");
 
 #include <dev/raidframe/raidframevar.h>
 
@@ -46,6 +46,7 @@
 #include "rf_dagffrd.h"
 #include "rf_general.h"
 #include "rf_dagffwr.h"
+#include "rf_map.h"
 
 /******************************************************************************
  *
@@ -174,6 +175,7 @@
        RF_ReconUnitNum_t which_ru;
        RF_RaidLayout_t *layoutPtr;
        RF_PhysDiskAddr_t *pda;
+       RF_VoidPointerListElem_t *vple;
 
        layoutPtr = &(raidPtr->Layout);
        parityStripeID = rf_RaidAddressToParityStripeID(layoutPtr, 
@@ -350,9 +352,12 @@
                }
        }
        if ((!allowBufferRecycle) || (i == nRodNodes)) {
-               RF_MallocAndAdd(xorNode->results[0],
-                               rf_RaidAddressToByte(raidPtr, raidPtr->Layout.sectorsPerStripeUnit),
-                               (void *), allocList);
+               xorNode->results[0] = rf_AllocIOBuffer(raidPtr, 
+                                                      rf_RaidAddressToByte(raidPtr, raidPtr->Layout.sectorsPerStripeUnit));
+               vple = rf_AllocVPListElem();
+               vple->p = xorNode->results[0];
+               vple->next = dag_h->iobufs;
+               dag_h->iobufs = vple;
        } else {
                /* this works because the only way we get here is if
                   allowBufferRecycle is true and we went through the
diff -r c18d1e8b5edb -r 4076b9820e6e sys/dev/raidframe/rf_dagutils.c
--- a/sys/dev/raidframe/rf_dagutils.c   Sat Mar 20 04:22:04 2004 +0000
+++ b/sys/dev/raidframe/rf_dagutils.c   Sat Mar 20 04:22:05 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rf_dagutils.c,v 1.40 2004/03/19 17:01:26 oster Exp $   */
+/*     $NetBSD: rf_dagutils.c,v 1.41 2004/03/20 04:22:05 oster Exp $   */
 /*
  * Copyright (c) 1995 Carnegie-Mellon University.
  * All rights reserved.
@@ -33,7 +33,7 @@
  *****************************************************************************/
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_dagutils.c,v 1.40 2004/03/19 17:01:26 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_dagutils.c,v 1.41 2004/03/20 04:22:05 oster Exp $");
 
 #include <dev/raidframe/raidframevar.h>
 
@@ -66,7 +66,6 @@
 static void rf_ValidateVisitedBits(RF_DagHeader_t *);
 #endif /* RF_DEBUG_VALIDATE_DAG */
 
-
 /* The maximum number of nodes in a DAG is bounded by
 
 (2 * raidPtr->Layout->numDataCol) + (1 * layoutPtr->numParityCol) + 
@@ -181,6 +180,7 @@
        RF_AccessStripeMapHeader_t *asmap, *t_asmap;
        RF_PhysDiskAddr_t *pda;
        RF_DagNode_t *tmpnode;
+       RF_VoidPointerListElem_t *tmpiobuf;
        RF_DagHeader_t *nextDag;
 
        while (dag_h) {
@@ -196,6 +196,13 @@
                        dag_h->pda_cleanup_list = dag_h->pda_cleanup_list->next;
                        rf_FreePhysDiskAddr(pda);
                }
+               while (dag_h->iobufs) {
+                       tmpiobuf = dag_h->iobufs;
+                       dag_h->iobufs = dag_h->iobufs->next;
+                       if (tmpiobuf->p)
+                               rf_FreeIOBuffer(dag_h->raidPtr, tmpiobuf->p);
+                       rf_FreeVPListElem(tmpiobuf);
+               }
                while (dag_h->nodes) {
                        tmpnode = dag_h->nodes;
                        dag_h->nodes = dag_h->nodes->list_next;
@@ -221,6 +228,9 @@
 #define RF_MAX_FREE_FUNCLIST 128
 #define RF_MIN_FREE_FUNCLIST  32
 
+#define RF_MAX_FREE_BUFFERS 128
+#define RF_MIN_FREE_BUFFERS  32
+
 static void rf_ShutdownDAGs(void *);
 static void 
 rf_ShutdownDAGs(void *ignored)
@@ -347,11 +357,63 @@
               RF_AllocListElem_t *allocList)
 {
        char   *p;
+       p = rf_AllocIOBuffer(raidPtr, pda->numSector << raidPtr->logBytesPerSector);
 
-       RF_MallocAndAdd(p, pda->numSector << raidPtr->logBytesPerSector,
-           (char *), allocList);
+       if (allocList) 
+               rf_AddToAllocList(allocList, p, pda->numSector << raidPtr->logBytesPerSector);
        return ((void *) p);
 }
+
+void *
+rf_AllocIOBuffer(RF_Raid_t *raidPtr, int size)
+{
+       void *p;
+
+       RF_ASSERT(size <= (raidPtr->Layout.sectorsPerStripeUnit << 
+                          raidPtr->logBytesPerSector));
+
+       p =  malloc( raidPtr->Layout.sectorsPerStripeUnit << 
+                                raidPtr->logBytesPerSector, 
+                                M_RAIDFRAME, M_NOWAIT);
+       if (!p) {
+               RF_LOCK_MUTEX(raidPtr->mutex);
+               if (raidPtr->iobuf_count > 0) {
+                       p = raidPtr->iobuf;
+                       raidPtr->iobuf = raidPtr->iobuf->next;
+                       raidPtr->iobuf_count--;
+               } else {
+#ifdef DIAGNOSTIC
+                       printf("raid%d: Help!  Out of emergency buffers!\n", raidPtr->raidid);
+#endif
+               }
+               RF_UNLOCK_MUTEX(raidPtr->mutex);
+               if (!p) {
+                       /* We didn't get a buffer... not much we can do other than wait, 
+                          and hope that someone frees up memory for us.. */
+                       p = malloc( raidPtr->Layout.sectorsPerStripeUnit << 
+                                   raidPtr->logBytesPerSector, 
+                                   M_RAIDFRAME, M_WAITOK);
+               }
+       }
+       return (p);
+}
+
+void
+rf_FreeIOBuffer(RF_Raid_t *raidPtr, void *p)
+{
+       RF_LOCK_MUTEX(raidPtr->mutex);
+       if (raidPtr->iobuf_count < raidPtr->numEmergencyBuffers) {
+               ((RF_IOBufHeader_t *)p)->next = raidPtr->iobuf;
+               raidPtr->iobuf = p;
+               raidPtr->iobuf_count++;
+       } else {
+               free(p, M_RAIDFRAME);
+       }
+       RF_UNLOCK_MUTEX(raidPtr->mutex);
+}
+
+
+
 #if RF_DEBUG_VALIDATE_DAG
 /******************************************************************************
  *
@@ -877,6 +939,7 @@
 {
        RF_RaidAddr_t sosRaidAddress, eosRaidAddress;
        RF_SectorNum_t sosNumSector, eosNumSector;
+       RF_VoidPointerListElem_t *vple;
 
        RF_ASSERT(asmap->numStripeUnitsAccessed > (layoutPtr->numDataCol / 2));
        /* generate an access map for the region of the array from start of
@@ -886,7 +949,11 @@
        if (!rf_RaidAddressStripeAligned(layoutPtr, asmap->raidAddress)) {
                sosRaidAddress = rf_RaidAddressOfPrevStripeBoundary(layoutPtr, asmap->raidAddress);
                sosNumSector = asmap->raidAddress - sosRaidAddress;
-               RF_MallocAndAdd(*sosBuffer, rf_RaidAddressToByte(raidPtr, sosNumSector), (char *), allocList);
+               *sosBuffer = rf_AllocIOBuffer(raidPtr, rf_RaidAddressToByte(raidPtr, sosNumSector));
+               vple = rf_AllocVPListElem();
+               vple->p = *sosBuffer;
+               vple->next = dag_h->iobufs;
+               dag_h->iobufs = vple;
                new_asm_h[0] = rf_MapAccess(raidPtr, sosRaidAddress, sosNumSector, *sosBuffer, RF_DONT_REMAP);
                new_asm_h[0]->next = dag_h->asmList;
                dag_h->asmList = new_asm_h[0];
@@ -902,7 +969,11 @@
        if (!rf_RaidAddressStripeAligned(layoutPtr, asmap->endRaidAddress)) {
                eosRaidAddress = asmap->endRaidAddress;
                eosNumSector = rf_RaidAddressOfNextStripeBoundary(layoutPtr, eosRaidAddress) - eosRaidAddress;
-               RF_MallocAndAdd(*eosBuffer, rf_RaidAddressToByte(raidPtr, eosNumSector), (char *), allocList);
+               *eosBuffer = rf_AllocIOBuffer(raidPtr, rf_RaidAddressToByte(raidPtr, eosNumSector));
+               vple = rf_AllocVPListElem();
+               vple->p = *eosBuffer;
+               vple->next = dag_h->iobufs;
+               dag_h->iobufs = vple;
                new_asm_h[1] = rf_MapAccess(raidPtr, eosRaidAddress, eosNumSector, *eosBuffer, RF_DONT_REMAP);
                new_asm_h[1]->next = dag_h->asmList;
                dag_h->asmList = new_asm_h[1];
diff -r c18d1e8b5edb -r 4076b9820e6e sys/dev/raidframe/rf_dagutils.h
--- a/sys/dev/raidframe/rf_dagutils.h   Sat Mar 20 04:22:04 2004 +0000
+++ b/sys/dev/raidframe/rf_dagutils.h   Sat Mar 20 04:22:05 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rf_dagutils.h,v 1.12 2004/03/19 17:01:26 oster Exp $   */
+/*     $NetBSD: rf_dagutils.h,v 1.13 2004/03/20 04:22:05 oster Exp $   */
 /*
  * Copyright (c) 1995 Carnegie-Mellon University.
  * All rights reserved.
@@ -85,9 +85,13 @@
 RF_FuncList_t *rf_AllocFuncList(void);
 void rf_FreeFuncList(RF_FuncList_t *);
 
+
+
 void   *rf_AllocBuffer(RF_Raid_t * raidPtr,
                       RF_PhysDiskAddr_t * pda, 
                       RF_AllocListElem_t * allocList);
+void *rf_AllocIOBuffer(RF_Raid_t *, int);
+void rf_FreeIOBuffer(RF_Raid_t *, void *);
 
 char   *rf_NodeStatusString(RF_DagNode_t * node);
 
diff -r c18d1e8b5edb -r 4076b9820e6e sys/dev/raidframe/rf_driver.c
--- a/sys/dev/raidframe/rf_driver.c     Sat Mar 20 04:22:04 2004 +0000
+++ b/sys/dev/raidframe/rf_driver.c     Sat Mar 20 04:22:05 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rf_driver.c,v 1.96 2004/03/13 02:31:12 oster Exp $     */
+/*     $NetBSD: rf_driver.c,v 1.97 2004/03/20 04:22:05 oster Exp $     */
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -73,7 +73,7 @@
 



Home | Main Index | Thread Index | Old Index