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