diff options
| author | oster <oster@NetBSD.org> | 2004-04-09 23:10:16 +0000 |
|---|---|---|
| committer | oster <oster@NetBSD.org> | 2004-04-09 23:10:16 +0000 |
| commit | 85611189b67852bd41f0ff78ef50caf23a104533 (patch) | |
| tree | 74c1cdd36c94c3b669c699742ff20965226dccfa /sys/dev/raidframe | |
| parent | 1a3822fca0d9f1c94a78481fd538c20dacc0f529 (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.c | 15 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_dag.h | 6 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_dagdegwr.c | 6 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_dagffwr.c | 10 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_dagutils.c | 122 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_dagutils.h | 9 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_desc.h | 10 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_driver.c | 52 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_netbsd.h | 7 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_raid.h | 9 |
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 */ |
