summaryrefslogtreecommitdiff
path: root/sys/dev/raidframe
diff options
context:
space:
mode:
authoroster <oster@NetBSD.org>2004-04-09 23:10:16 +0000
committeroster <oster@NetBSD.org>2004-04-09 23:10:16 +0000
commit85611189b67852bd41f0ff78ef50caf23a104533 (patch)
tree74c1cdd36c94c3b669c699742ff20965226dccfa /sys/dev/raidframe
parent1a3822fca0d9f1c94a78481fd538c20dacc0f529 (diff)
These changes complete the effective removal of malloc() from all
write paths within RAIDframe. They also resolve the "panics with RAID 5 sets with more than 3 components" issue which was present (briefly) in the commits which were previously supposed to address the malloc() issue. With this new code the 5-component RAID 5 set panics are now gone. It is also now also possible to swap to RAID 5. The changes made are: 1) Introduce rf_AllocStripeBuffer() and rf_FreeStripeBuffer() to allocate/free one stripe's worth of space. rf_AllocStripeBuffer() is used in rf_MapUnaccessedPortionOfStripe() where it is not sufficient to allocate memory using just rf_AllocBuffer(). rf_FreeStripeBuffer() is called from rf_FreeRaidAccDesc(), well after the DAG is finished. 2) Add a set of emergency "stripe buffers" to struct RF_Raid_s. Arrange for their initialization in rf_Configure(). In low-memory situations these buffers will be returned by rf_AllocStripeBuffer() and re-populated by rf_FreeStripeBuffer(). 3) Move RF_VoidPointerListElem_t *iobufs from the dagHeader into into struct RF_RaidAccessDesc_s. This is more consistent with the original code, and will not result in items being freed "too early". 4) Add a RF_RaidAccessDesc_t *desc to RF_DagHeader_s so that we have a way to find desc->iobufs. 5) Arrange for desc in the DagHeader to be initialized in InitHdrNode(). 6) Don't cleanup iobufs in rf_FreeDAG() -- the freeing is now delayed until rf_FreeRaidAccDesc() (which is how the original code handled the allocList, and for which there seem to be some subtle, undocumented assumptions). 7) Rename rf_AllocBuffer2() to be rf_AllocBuffer() and remove the former rf_AllocBuffer(). Fix all callers of rf_AllocBuffer(). (This was how it was *supposed* to be after the last time these changes were made, before they were backed out). 8) Remove RF_IOBufHeader and all references to it. 9) Remove desc->cleanupList and all references to it. Fixes PR#20191
Diffstat (limited to 'sys/dev/raidframe')
-rw-r--r--sys/dev/raidframe/rf_aselect.c15
-rw-r--r--sys/dev/raidframe/rf_dag.h6
-rw-r--r--sys/dev/raidframe/rf_dagdegwr.c6
-rw-r--r--sys/dev/raidframe/rf_dagffwr.c10
-rw-r--r--sys/dev/raidframe/rf_dagutils.c122
-rw-r--r--sys/dev/raidframe/rf_dagutils.h9
-rw-r--r--sys/dev/raidframe/rf_desc.h10
-rw-r--r--sys/dev/raidframe/rf_driver.c52
-rw-r--r--sys/dev/raidframe/rf_netbsd.h7
-rw-r--r--sys/dev/raidframe/rf_raid.h9
10 files changed, 169 insertions, 77 deletions
diff --git a/sys/dev/raidframe/rf_aselect.c b/sys/dev/raidframe/rf_aselect.c
index 6c342b77712..9abafa7944c 100644
--- a/sys/dev/raidframe/rf_aselect.c
+++ b/sys/dev/raidframe/rf_aselect.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_aselect.c,v 1.19 2004/03/20 21:25:55 oster Exp $ */
+/* $NetBSD: rf_aselect.c,v 1.20 2004/04/09 23:10:16 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -33,7 +33,7 @@
*****************************************************************************/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_aselect.c,v 1.19 2004/03/20 21:25:55 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_aselect.c,v 1.20 2004/04/09 23:10:16 oster Exp $");
#include <dev/raidframe/raidframevar.h>
@@ -46,7 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: rf_aselect.c,v 1.19 2004/03/20 21:25:55 oster Exp $"
#include "rf_desc.h"
#include "rf_map.h"
-static void InitHdrNode(RF_DagHeader_t **, RF_Raid_t *);
+static void InitHdrNode(RF_DagHeader_t **, RF_Raid_t *, RF_RaidAccessDesc_t *);
int rf_SelectAlgorithm(RF_RaidAccessDesc_t *, RF_RaidAccessFlags_t);
/******************************************************************************
@@ -55,7 +55,7 @@ int rf_SelectAlgorithm(RF_RaidAccessDesc_t *, RF_RaidAccessFlags_t);
*
*****************************************************************************/
static void
-InitHdrNode(RF_DagHeader_t **hdr, RF_Raid_t *raidPtr)
+InitHdrNode(RF_DagHeader_t **hdr, RF_Raid_t *raidPtr, RF_RaidAccessDesc_t *desc)
{
/* create and initialize dag hdr */
*hdr = rf_AllocDAGHeader();
@@ -65,6 +65,7 @@ InitHdrNode(RF_DagHeader_t **hdr, RF_Raid_t *raidPtr)
(*hdr)->nodes = NULL;
(*hdr)->raidPtr = raidPtr;
(*hdr)->next = NULL;
+ (*hdr)->desc = desc;
}
/******************************************************************************
@@ -382,7 +383,7 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
for (k = 0; k < physPtr->numSector; k++) {
/* create a dag for
* this block */
- InitHdrNode(&tempdag_h, raidPtr);
+ InitHdrNode(&tempdag_h, raidPtr, desc);
dagList->numDags++;
if (dag_h == NULL) {
dag_h = tempdag_h;
@@ -402,7 +403,7 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
stripeUnitNum++;
} else {
/* create a dag for this unit */
- InitHdrNode(&tempdag_h, raidPtr);
+ InitHdrNode(&tempdag_h, raidPtr, desc);
dagList->numDags++;
if (dag_h == NULL) {
dag_h = tempdag_h;
@@ -424,7 +425,7 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
failed_stripe = failed_stripe->next;
} else {
/* Create a dag for this parity stripe */
- InitHdrNode(&tempdag_h, raidPtr);
+ InitHdrNode(&tempdag_h, raidPtr, desc);
dagList->numDags++;
if (dag_h == NULL) {
dag_h = tempdag_h;
diff --git a/sys/dev/raidframe/rf_dag.h b/sys/dev/raidframe/rf_dag.h
index 38f9eac59e1..d2ebf9b7ddd 100644
--- a/sys/dev/raidframe/rf_dag.h
+++ b/sys/dev/raidframe/rf_dag.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_dag.h,v 1.15 2004/03/20 04:22:05 oster Exp $ */
+/* $NetBSD: rf_dag.h,v 1.16 2004/04/09 23:10:17 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -43,6 +43,7 @@
#include "rf_layout.h"
#include "rf_dagflags.h"
#include "rf_acctrace.h"
+#include "rf_desc.h"
#define RF_THREAD_CONTEXT 0 /* we were invoked from thread context */
#define RF_INTR_CONTEXT 1 /* we were invoked from interrupt context */
@@ -174,10 +175,9 @@ struct RF_DagHeader_s {
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 */
+ RF_RaidAccessDesc_t *desc; /* ptr to descriptor for this access */
void *bp; /* the bp for this I/O passed down from the
* file system. ignored outside kernel */
};
diff --git a/sys/dev/raidframe/rf_dagdegwr.c b/sys/dev/raidframe/rf_dagdegwr.c
index 16f00b1ea09..66f3bcadbb6 100644
--- a/sys/dev/raidframe/rf_dagdegwr.c
+++ b/sys/dev/raidframe/rf_dagdegwr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_dagdegwr.c,v 1.23 2004/03/23 21:53:36 oster Exp $ */
+/* $NetBSD: rf_dagdegwr.c,v 1.24 2004/04/09 23:10:16 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.23 2004/03/23 21:53:36 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_dagdegwr.c,v 1.24 2004/04/09 23:10:16 oster Exp $");
#include <dev/raidframe/raidframevar.h>
@@ -368,7 +368,7 @@ rf_CommonCreateSimpleDegradedWriteDAG(RF_Raid_t *raidPtr,
parityPDA->numSector = failedPDA->numSector;
if (!xorTargetBuf) {
- xorTargetBuf = rf_AllocBuffer(raidPtr, rf_RaidAddressToByte(raidPtr, failedPDA->numSector), allocList);
+ xorTargetBuf = rf_AllocBuffer(raidPtr, dag_h, rf_RaidAddressToByte(raidPtr, failedPDA->numSector));
}
/* init the Wnp node */
rf_InitNode(wnpNode, rf_wait, RF_FALSE, rf_DiskWriteFunc, rf_DiskWriteUndoFunc,
diff --git a/sys/dev/raidframe/rf_dagffwr.c b/sys/dev/raidframe/rf_dagffwr.c
index 048040de911..4aede30317b 100644
--- a/sys/dev/raidframe/rf_dagffwr.c
+++ b/sys/dev/raidframe/rf_dagffwr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_dagffwr.c,v 1.26 2004/03/23 21:55:23 oster Exp $ */
+/* $NetBSD: rf_dagffwr.c,v 1.27 2004/04/09 23:10:16 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.26 2004/03/23 21:55:23 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_dagffwr.c,v 1.27 2004/04/09 23:10:16 oster Exp $");
#include <dev/raidframe/raidframevar.h>
@@ -351,7 +351,7 @@ rf_CommonCreateLargeWriteDAG(RF_Raid_t *raidPtr, RF_AccessStripeMap_t *asmap,
}
}
if ((!allowBufferRecycle) || (i == nRodNodes)) {
- xorNode->results[0] = rf_AllocBuffer(raidPtr, rf_RaidAddressToByte(raidPtr, raidPtr->Layout.sectorsPerStripeUnit), allocList);
+ xorNode->results[0] = rf_AllocBuffer(raidPtr, dag_h, rf_RaidAddressToByte(raidPtr, raidPtr->Layout.sectorsPerStripeUnit));
} else {
/* this works because the only way we get here is if
allowBufferRecycle is true and we went through the
@@ -692,7 +692,7 @@ rf_CommonCreateSmallWriteDAG(RF_Raid_t *raidPtr, RF_AccessStripeMap_t *asmap,
/* physical disk addr desc */
tmpreadDataNode->params[0].p = pda;
/* buffer to hold old data */
- tmpreadDataNode->params[1].p = rf_AllocBuffer(raidPtr, pda->numSector << raidPtr->logBytesPerSector, allocList);
+ tmpreadDataNode->params[1].p = rf_AllocBuffer(raidPtr, dag_h, pda->numSector << raidPtr->logBytesPerSector);
tmpreadDataNode->params[2].v = parityStripeID;
tmpreadDataNode->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY,
which_ru);
@@ -715,7 +715,7 @@ rf_CommonCreateSmallWriteDAG(RF_Raid_t *raidPtr, RF_AccessStripeMap_t *asmap,
dag_h, "Rop", allocList);
tmpreadParityNode->params[0].p = pda;
/* buffer to hold old parity */
- tmpreadParityNode->params[1].p = rf_AllocBuffer(raidPtr, pda->numSector << raidPtr->logBytesPerSector, allocList);
+ tmpreadParityNode->params[1].p = rf_AllocBuffer(raidPtr, dag_h, pda->numSector << raidPtr->logBytesPerSector);
tmpreadParityNode->params[2].v = parityStripeID;
tmpreadParityNode->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY,
which_ru);
diff --git a/sys/dev/raidframe/rf_dagutils.c b/sys/dev/raidframe/rf_dagutils.c
index 97f23787457..77b82315e59 100644
--- a/sys/dev/raidframe/rf_dagutils.c
+++ b/sys/dev/raidframe/rf_dagutils.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_dagutils.c,v 1.43 2004/03/23 21:53:36 oster Exp $ */
+/* $NetBSD: rf_dagutils.c,v 1.44 2004/04/09 23:10:16 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.43 2004/03/23 21:53:36 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_dagutils.c,v 1.44 2004/04/09 23:10:16 oster Exp $");
#include <dev/raidframe/raidframevar.h>
@@ -180,7 +180,6 @@ rf_FreeDAG(RF_DagHeader_t *dag_h)
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,13 +195,6 @@ rf_FreeDAG(RF_DagHeader_t *dag_h)
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;
@@ -349,24 +341,76 @@ rf_FreeFuncList(RF_FuncList_t *funcList)
pool_put(&rf_pools.funclist, funcList);
}
-
-
-/* allocates a buffer big enough to hold the data described by the
-caller (ie. the data of the associated PDA). Glue this buffer
-into our dag_h cleanup structure. */
+/* allocates a stripe buffer -- a buffer large enough to hold all the data
+ in an entire stripe.
+*/
void *
-rf_AllocBuffer(RF_Raid_t *raidPtr, int size, RF_AllocListElem_t * allocList)
+rf_AllocStripeBuffer(RF_Raid_t *raidPtr, RF_DagHeader_t *dag_h, int size)
{
+ RF_VoidPointerListElem_t *vple;
void *p;
-
- RF_MallocAndAdd(p, size, (char *), allocList);
- return ((void *) p);
+
+ RF_ASSERT((size <= (raidPtr->numCol * (raidPtr->Layout.sectorsPerStripeUnit <<
+ raidPtr->logBytesPerSector))));
+
+ p = malloc( raidPtr->numCol * (raidPtr->Layout.sectorsPerStripeUnit <<
+ raidPtr->logBytesPerSector),
+ M_RAIDFRAME, M_NOWAIT);
+ if (!p) {
+ RF_LOCK_MUTEX(raidPtr->mutex);
+ if (raidPtr->stripebuf_count > 0) {
+ vple = raidPtr->stripebuf;
+ raidPtr->stripebuf = vple->next;
+ p = vple->p;
+ rf_FreeVPListElem(vple);
+ raidPtr->stripebuf_count--;
+ } else {
+#ifdef DIAGNOSTIC
+ printf("raid%d: Help! Out of emergency full-stripe 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->numCol * (raidPtr->Layout.sectorsPerStripeUnit <<
+ raidPtr->logBytesPerSector), M_RAIDFRAME, M_WAITOK);
+ }
+ }
+ memset(p, 0, raidPtr->numCol * (raidPtr->Layout.sectorsPerStripeUnit << raidPtr->logBytesPerSector));
+
+ vple = rf_AllocVPListElem();
+ vple->p = p;
+ vple->next = dag_h->desc->stripebufs;
+ dag_h->desc->stripebufs = vple;
+
+ return (p);
}
-void *
-rf_AllocBuffer2(RF_Raid_t *raidPtr, RF_DagHeader_t *dag_h, int size)
+void
+rf_FreeStripeBuffer(RF_Raid_t *raidPtr, RF_VoidPointerListElem_t *vple)
+{
+ RF_LOCK_MUTEX(raidPtr->mutex);
+ if (raidPtr->stripebuf_count < raidPtr->numEmergencyStripeBuffers) {
+ /* just tack it in */
+ vple->next = raidPtr->stripebuf;
+ raidPtr->stripebuf = vple;
+ raidPtr->stripebuf_count++;
+ } else {
+ free(vple->p, M_RAIDFRAME);
+ rf_FreeVPListElem(vple);
+ }
+ RF_UNLOCK_MUTEX(raidPtr->mutex);
+}
+
+/* allocates a buffer big enough to hold the data described by the
+caller (ie. the data of the associated PDA). Glue this buffer
+into our dag_h cleanup structure. */
+
+void *
+rf_AllocBuffer(RF_Raid_t *raidPtr, RF_DagHeader_t *dag_h, int size)
{
RF_VoidPointerListElem_t *vple;
void *p;
@@ -374,8 +418,8 @@ rf_AllocBuffer2(RF_Raid_t *raidPtr, RF_DagHeader_t *dag_h, int size)
p = rf_AllocIOBuffer(raidPtr, size);
vple = rf_AllocVPListElem();
vple->p = p;
- vple->next = dag_h->iobufs;
- dag_h->iobufs = vple;
+ vple->next = dag_h->desc->iobufs;
+ dag_h->desc->iobufs = vple;
return (p);
}
@@ -383,10 +427,11 @@ rf_AllocBuffer2(RF_Raid_t *raidPtr, RF_DagHeader_t *dag_h, int size)
void *
rf_AllocIOBuffer(RF_Raid_t *raidPtr, int size)
{
+ RF_VoidPointerListElem_t *vple;
void *p;
- RF_ASSERT(size <= (raidPtr->Layout.sectorsPerStripeUnit <<
- raidPtr->logBytesPerSector));
+ RF_ASSERT((size <= (raidPtr->Layout.sectorsPerStripeUnit <<
+ raidPtr->logBytesPerSector)));
p = malloc( raidPtr->Layout.sectorsPerStripeUnit <<
raidPtr->logBytesPerSector,
@@ -394,8 +439,10 @@ rf_AllocIOBuffer(RF_Raid_t *raidPtr, int size)
if (!p) {
RF_LOCK_MUTEX(raidPtr->mutex);
if (raidPtr->iobuf_count > 0) {
- p = raidPtr->iobuf;
- raidPtr->iobuf = raidPtr->iobuf->next;
+ vple = raidPtr->iobuf;
+ raidPtr->iobuf = vple->next;
+ p = vple->p;
+ rf_FreeVPListElem(vple);
raidPtr->iobuf_count--;
} else {
#ifdef DIAGNOSTIC
@@ -411,19 +458,22 @@ rf_AllocIOBuffer(RF_Raid_t *raidPtr, int size)
M_RAIDFRAME, M_WAITOK);
}
}
+ memset(p, 0, raidPtr->Layout.sectorsPerStripeUnit << raidPtr->logBytesPerSector);
return (p);
}
void
-rf_FreeIOBuffer(RF_Raid_t *raidPtr, void *p)
+rf_FreeIOBuffer(RF_Raid_t *raidPtr, RF_VoidPointerListElem_t *vple)
{
RF_LOCK_MUTEX(raidPtr->mutex);
if (raidPtr->iobuf_count < raidPtr->numEmergencyBuffers) {
- ((RF_IOBufHeader_t *)p)->next = raidPtr->iobuf;
- raidPtr->iobuf = p;
+ /* just tack it in */
+ vple->next = raidPtr->iobuf;
+ raidPtr->iobuf = vple;
raidPtr->iobuf_count++;
} else {
- free(p, M_RAIDFRAME);
+ free(vple->p, M_RAIDFRAME);
+ rf_FreeVPListElem(vple);
}
RF_UNLOCK_MUTEX(raidPtr->mutex);
}
@@ -964,7 +1014,7 @@ rf_MapUnaccessedPortionOfStripe(RF_Raid_t *raidPtr,
if (!rf_RaidAddressStripeAligned(layoutPtr, asmap->raidAddress)) {
sosRaidAddress = rf_RaidAddressOfPrevStripeBoundary(layoutPtr, asmap->raidAddress);
sosNumSector = asmap->raidAddress - sosRaidAddress;
- *sosBuffer = rf_AllocBuffer(raidPtr, rf_RaidAddressToByte(raidPtr, sosNumSector), allocList);
+ *sosBuffer = rf_AllocStripeBuffer(raidPtr, dag_h, rf_RaidAddressToByte(raidPtr, sosNumSector));
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];
@@ -980,7 +1030,7 @@ rf_MapUnaccessedPortionOfStripe(RF_Raid_t *raidPtr,
if (!rf_RaidAddressStripeAligned(layoutPtr, asmap->endRaidAddress)) {
eosRaidAddress = asmap->endRaidAddress;
eosNumSector = rf_RaidAddressOfNextStripeBoundary(layoutPtr, eosRaidAddress) - eosRaidAddress;
- *eosBuffer = rf_AllocBuffer(raidPtr, rf_RaidAddressToByte(raidPtr, eosNumSector), allocList);
+ *eosBuffer = rf_AllocStripeBuffer(raidPtr, dag_h, rf_RaidAddressToByte(raidPtr, eosNumSector));
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];
@@ -1081,7 +1131,7 @@ rf_GenerateFailedAccessASMs(RF_Raid_t *raidPtr, RF_AccessStripeMap_t *asmap,
dag_h->asmList = new_asm_h[0];
for (pda = new_asm_h[0]->stripeMap->physInfo; pda; pda = pda->next) {
rf_RangeRestrictPDA(raidPtr, failedPDA, pda, RF_RESTRICT_NOBUFFER, 0);
- pda->bufPtr = rf_AllocBuffer(raidPtr, pda->numSector << raidPtr->logBytesPerSector, allocList);
+ pda->bufPtr = rf_AllocBuffer(raidPtr, dag_h, pda->numSector << raidPtr->logBytesPerSector);
}
(*nXorBufs) += new_asm_h[0]->stripeMap->numStripeUnitsAccessed;
}
@@ -1090,14 +1140,14 @@ rf_GenerateFailedAccessASMs(RF_Raid_t *raidPtr, RF_AccessStripeMap_t *asmap,
dag_h->asmList = new_asm_h[1];
for (pda = new_asm_h[1]->stripeMap->physInfo; pda; pda = pda->next) {
rf_RangeRestrictPDA(raidPtr, failedPDA, pda, RF_RESTRICT_NOBUFFER, 0);
- pda->bufPtr = rf_AllocBuffer(raidPtr, pda->numSector << raidPtr->logBytesPerSector, allocList);
+ pda->bufPtr = rf_AllocBuffer(raidPtr, dag_h, pda->numSector << raidPtr->logBytesPerSector);
}
(*nXorBufs) += new_asm_h[1]->stripeMap->numStripeUnitsAccessed;
}
/* allocate a buffer for parity */
if (rpBufPtr)
- *rpBufPtr = rf_AllocBuffer(raidPtr, failedPDA->numSector << raidPtr->logBytesPerSector, allocList);
+ *rpBufPtr = rf_AllocBuffer(raidPtr, dag_h, failedPDA->numSector << raidPtr->logBytesPerSector);
/* the last step is to figure out how many more distinct buffers need
* to get xor'd to produce the missing unit. there's one for each
diff --git a/sys/dev/raidframe/rf_dagutils.h b/sys/dev/raidframe/rf_dagutils.h
index b83b24923c6..cf0739c5857 100644
--- a/sys/dev/raidframe/rf_dagutils.h
+++ b/sys/dev/raidframe/rf_dagutils.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_dagutils.h,v 1.16 2004/03/23 21:53:36 oster Exp $ */
+/* $NetBSD: rf_dagutils.h,v 1.17 2004/04/09 23:10:16 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -81,10 +81,11 @@ void rf_FreeDAGPCache(void *);
RF_FuncList_t *rf_AllocFuncList(void);
void rf_FreeFuncList(RF_FuncList_t *);
-void *rf_AllocBuffer(RF_Raid_t *, int, RF_AllocListElem_t *);
-void *rf_AllocBuffer2(RF_Raid_t *, RF_DagHeader_t *, int);
+void *rf_AllocBuffer(RF_Raid_t *, RF_DagHeader_t *, int);
void *rf_AllocIOBuffer(RF_Raid_t *, int);
-void rf_FreeIOBuffer(RF_Raid_t *, void *);
+void rf_FreeIOBuffer(RF_Raid_t *, RF_VoidPointerListElem_t *);
+void *rf_AllocStripeBuffer(RF_Raid_t *, RF_DagHeader_t *, int);
+void rf_FreeStripeBuffer(RF_Raid_t *, RF_VoidPointerListElem_t *);
char *rf_NodeStatusString(RF_DagNode_t *);
void rf_PrintNodeInfoString(RF_DagNode_t *);
diff --git a/sys/dev/raidframe/rf_desc.h b/sys/dev/raidframe/rf_desc.h
index eec35f21006..2ee060901cd 100644
--- a/sys/dev/raidframe/rf_desc.h
+++ b/sys/dev/raidframe/rf_desc.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_desc.h,v 1.12 2004/03/13 02:31:12 oster Exp $ */
+/* $NetBSD: rf_desc.h,v 1.13 2004/04/09 23:10:16 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -34,6 +34,7 @@
#include "rf_archs.h"
#include "rf_etimer.h"
#include "rf_dag.h"
+#include "rf_layout.h"
struct RF_RaidReconDesc_s {
RF_Raid_t *raidPtr; /* raid device descriptor */
@@ -78,6 +79,11 @@ struct RF_RaidAccessDesc_s {
RF_AccessState_t *states; /* array of states to be run */
int status; /* pass/fail status of the last operation */
RF_DagList_t *dagList; /* list of dag lists, one list per stripe */
+ RF_VoidPointerListElem_t *iobufs; /* iobufs that need to be cleaned
+ up at the end of this IO */
+ RF_VoidPointerListElem_t *stripebufs; /* stripe buffers that need to
+ be cleaned up at the end of
+ this IO */
RF_AccessStripeMapHeader_t *asmap; /* the asm for this I/O */
void *bp; /* buf pointer for this RAID acc. ignored
* outside the kernel */
@@ -86,8 +92,6 @@ struct RF_RaidAccessDesc_s {
void (*callbackFunc) (RF_CBParam_t); /* callback function for this
* I/O */
void *callbackArg; /* arg to give to callback func */
- RF_AllocListElem_t *cleanupList; /* memory to be freed at the
- * end of the access */
RF_RaidAccessDesc_t *next;
int async_flag;
RF_Etimer_t timer; /* used for timing this access */
diff --git a/sys/dev/raidframe/rf_driver.c b/sys/dev/raidframe/rf_driver.c
index c341d232d0e..eba58b6f105 100644
--- a/sys/dev/raidframe/rf_driver.c
+++ b/sys/dev/raidframe/rf_driver.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_driver.c,v 1.98 2004/03/21 21:08:08 oster Exp $ */
+/* $NetBSD: rf_driver.c,v 1.99 2004/04/09 23:10:16 oster Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -73,7 +73,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.98 2004/03/21 21:08:08 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.99 2004/04/09 23:10:16 oster Exp $");
#include "opt_raid_diagnostic.h"
@@ -280,7 +280,8 @@ int
rf_Configure(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr, RF_AutoConfig_t *ac)
{
RF_RowCol_t col;
- RF_IOBufHeader_t *tmpbuf;
+ void *tmpbuf;
+ RF_VoidPointerListElem_t *vple;
int rc, i;
RF_LOCK_LKMGR_MUTEX(configureMutex);
@@ -410,8 +411,10 @@ rf_Configure(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr, RF_AutoConfig_t *ac)
raidPtr->logBytesPerSector,
M_RAIDFRAME, M_NOWAIT);
if (tmpbuf) {
- tmpbuf->next = raidPtr->iobuf;
- raidPtr->iobuf = tmpbuf;
+ vple = rf_AllocVPListElem();
+ vple->p= tmpbuf;
+ vple->next = raidPtr->iobuf;
+ raidPtr->iobuf = vple;
raidPtr->iobuf_count++;
} else {
printf("raid%d: failed to allocate emergency buffer!\n",
@@ -419,6 +422,25 @@ rf_Configure(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr, RF_AutoConfig_t *ac)
}
}
+ /* XXX next line needs tuning too... */
+ raidPtr->numEmergencyStripeBuffers = 10;
+ for (i = 0; i < raidPtr->numEmergencyStripeBuffers; i++) {
+ tmpbuf = malloc( raidPtr->numCol * (raidPtr->Layout.sectorsPerStripeUnit <<
+ raidPtr->logBytesPerSector),
+ M_RAIDFRAME, M_NOWAIT);
+ if (tmpbuf) {
+ vple = rf_AllocVPListElem();
+ vple->p= tmpbuf;
+ vple->next = raidPtr->stripebuf;
+ raidPtr->stripebuf = vple;
+ raidPtr->stripebuf_count++;
+ } else {
+ printf("raid%d: failed to allocate emergency stripe buffer!\n",
+ raidPtr->raidid);
+ }
+ }
+
+
raidPtr->valid = 1;
printf("raid%d: %s\n", raidPtr->raidid,
@@ -492,6 +514,7 @@ rf_AllocRaidAccDesc(RF_Raid_t *raidPtr, RF_IoType_t type,
desc->flags = flags;
desc->states = states;
desc->state = 0;
+ desc->dagList = NULL;
desc->status = 0;
#if RF_ACC_TRACE > 0
@@ -500,8 +523,9 @@ rf_AllocRaidAccDesc(RF_Raid_t *raidPtr, RF_IoType_t type,
desc->callbackFunc = NULL;
desc->callbackArg = NULL;
desc->next = NULL;
- desc->cleanupList = NULL;
- rf_MakeAllocList(desc->cleanupList);
+ desc->iobufs = NULL;
+ desc->stripebufs = NULL;
+
return (desc);
}
@@ -510,6 +534,7 @@ rf_FreeRaidAccDesc(RF_RaidAccessDesc_t *desc)
{
RF_Raid_t *raidPtr = desc->raidPtr;
RF_DagList_t *dagList, *temp;
+ RF_VoidPointerListElem_t *tmp;
RF_ASSERT(desc);
@@ -521,7 +546,18 @@ rf_FreeRaidAccDesc(RF_RaidAccessDesc_t *desc)
rf_FreeDAGList(temp);
}
- rf_FreeAllocList(desc->cleanupList);
+ while (desc->iobufs) {
+ tmp = desc->iobufs;
+ desc->iobufs = desc->iobufs->next;
+ rf_FreeIOBuffer(raidPtr, tmp);
+ }
+
+ while (desc->stripebufs) {
+ tmp = desc->stripebufs;
+ desc->stripebufs = desc->stripebufs->next;
+ rf_FreeStripeBuffer(raidPtr, tmp);
+ }
+
pool_put(&rf_pools.rad, desc);
RF_LOCK_MUTEX(rf_rad_lock);
raidPtr->nAccOutstanding--;
diff --git a/sys/dev/raidframe/rf_netbsd.h b/sys/dev/raidframe/rf_netbsd.h
index 41526440a07..ff5f2cb6080 100644
--- a/sys/dev/raidframe/rf_netbsd.h
+++ b/sys/dev/raidframe/rf_netbsd.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_netbsd.h,v 1.19 2004/03/20 04:22:05 oster Exp $ */
+/* $NetBSD: rf_netbsd.h,v 1.20 2004/04/09 23:10:16 oster Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -92,11 +92,6 @@ struct RF_Pools_s {
extern struct RF_Pools_s rf_pools;
void rf_pool_init(struct pool *, size_t, char *, size_t, size_t);
-typedef struct RF_IOBufHeader_s {
- struct RF_IOBufHeader_s *next;
-} RF_IOBufHeader_t;
-
-
/* XXX probably belongs in a different .h file. */
typedef struct RF_AutoConfig_s {
char devname[56]; /* the name of this component */
diff --git a/sys/dev/raidframe/rf_raid.h b/sys/dev/raidframe/rf_raid.h
index 8fa04f4ff67..e2050bfb6ee 100644
--- a/sys/dev/raidframe/rf_raid.h
+++ b/sys/dev/raidframe/rf_raid.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_raid.h,v 1.32 2004/03/20 04:22:05 oster Exp $ */
+/* $NetBSD: rf_raid.h,v 1.33 2004/04/09 23:10:16 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -165,9 +165,14 @@ struct RF_Raid_s {
struct simplelock iodone_lock;
- RF_IOBufHeader_t *iobuf; /* I/O buffer free list */
+ RF_VoidPointerListElem_t *iobuf; /* I/O buffer free list */
int iobuf_count; /* count of I/O buffers on the freelist */
int numEmergencyBuffers; /* number of these buffers to pre-allocate */
+
+ RF_VoidPointerListElem_t *stripebuf; /* Full-stripe buffer free list */
+ int stripebuf_count; /* count of full-stripe buffers on the freelist */
+ int numEmergencyStripeBuffers; /* number of these buffers to pre-allocate */
+
/*
* Cleanup stuff
*/