summaryrefslogtreecommitdiff
path: root/sys/dev/raidframe
diff options
context:
space:
mode:
authoroster <oster@NetBSD.org>2004-02-27 02:55:17 +0000
committeroster <oster@NetBSD.org>2004-02-27 02:55:17 +0000
commit24099528e97f96fd6010a09ce7f52d9e20d837ae (patch)
tree023cb03d35a6288a9da439d4cd34fa0084e39e1b /sys/dev/raidframe
parentd177d4c74457537d91b11946738c129eb2ab1419 (diff)
Use a dynamically allocated linked list of dagLists instead of using a
dynamically allocated variable-sized array (dagArray). Convert code to use the new linked list stuff instead of the array stuff (the ratio of one dagList per stripe still applies). The big advantage is in being able to more efficiently allocate the dagLists on-the-fly, and not have to know the size(s) of the array beforehand.
Diffstat (limited to 'sys/dev/raidframe')
-rw-r--r--sys/dev/raidframe/rf_aselect.c35
-rw-r--r--sys/dev/raidframe/rf_dag.h3
-rw-r--r--sys/dev/raidframe/rf_dagutils.c37
-rw-r--r--sys/dev/raidframe/rf_dagutils.h5
-rw-r--r--sys/dev/raidframe/rf_desc.h4
-rw-r--r--sys/dev/raidframe/rf_driver.c16
-rw-r--r--sys/dev/raidframe/rf_states.c76
7 files changed, 127 insertions, 49 deletions
diff --git a/sys/dev/raidframe/rf_aselect.c b/sys/dev/raidframe/rf_aselect.c
index cb44df9b1aa..d62ab82f889 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.11 2004/01/02 21:41:08 oster Exp $ */
+/* $NetBSD: rf_aselect.c,v 1.12 2004/02/27 02:55:18 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.11 2004/01/02 21:41:08 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_aselect.c,v 1.12 2004/02/27 02:55:18 oster Exp $");
#include <dev/raidframe/raidframevar.h>
@@ -82,8 +82,8 @@ InitHdrNode(RF_DagHeader_t **hdr, RF_Raid_t *raidPtr)
*
* Create a DAG to do a read or write operation.
*
- * create an array of dagLists, one list per parity stripe.
- * return the lists in the array desc->dagArray.
+ * create a list of dagLists, one list per parity stripe.
+ * return the lists in the desc->dagList (which is a list of lists).
*
* Normally, each list contains one dag for the entire stripe. In some
* tricky cases, we break this into multiple dags, either one per stripe
@@ -123,6 +123,7 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
RF_AccessStripeMap_t *asmap = asm_h->stripeMap;
RF_AccessStripeMap_t *asm_p;
RF_DagHeader_t *dag_h = NULL, *tempdag_h, *lastdag_h;
+ RF_DagList_t *dagList, *dagListend;
int i, j, k;
RF_VoidFuncPtr *stripeFuncs, normalStripeFuncs[MAXNSTRIPES];
RF_AccessStripeMap_t *asm_up, *asm_bp;
@@ -273,13 +274,25 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
stripeNum = 0;
stripeUnitNum = 0;
- /* create an array of dagLists and fill them in */
- RF_MallocAndAdd(desc->dagArray, desc->numStripes * sizeof(RF_DagList_t), (RF_DagList_t *), desc->cleanupList);
+ /* create a list of dagLists and fill them in */
+
+ dagListend = NULL;
for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
/* grab dag header for this stripe */
dag_h = NULL;
- desc->dagArray[i].desc = desc;
+
+ dagList = rf_AllocDAGList();
+
+ /* always tack the new dagList onto the end of the list... */
+ if (dagListend == NULL) {
+ desc->dagList = dagList;
+ } else {
+ dagListend->next = dagList;
+ }
+ dagListend = dagList;
+
+ dagList->desc = desc;
if (stripeFuncs[i] == (RF_VoidFuncPtr) NULL) {
/* use bailout functions for this stripe */
@@ -292,7 +305,7 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
/* create a dag for
* this block */
InitHdrNode(&tempdag_h, raidPtr);
- desc->dagArray[i].numDags++;
+ dagList->numDags++;
if (dag_h == NULL) {
dag_h = tempdag_h;
} else {
@@ -309,7 +322,7 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
} else {
/* create a dag for this unit */
InitHdrNode(&tempdag_h, raidPtr);
- desc->dagArray[i].numDags++;
+ dagList->numDags++;
if (dag_h == NULL) {
dag_h = tempdag_h;
} else {
@@ -328,7 +341,7 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
} else {
/* Create a dag for this parity stripe */
InitHdrNode(&tempdag_h, raidPtr);
- desc->dagArray[i].numDags++;
+ dagList->numDags++;
if (dag_h == NULL) {
dag_h = tempdag_h;
} else {
@@ -338,7 +351,7 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
(stripeFuncs[i]) (raidPtr, asm_p, tempdag_h, bp, flags, tempdag_h->allocList);
}
- desc->dagArray[i].dags = dag_h;
+ dagList->dags = dag_h;
}
RF_ASSERT(i == desc->numStripes);
diff --git a/sys/dev/raidframe/rf_dag.h b/sys/dev/raidframe/rf_dag.h
index 7a3c2014a32..9f830748b93 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.7 2002/09/23 23:53:54 oster Exp $ */
+/* $NetBSD: rf_dag.h,v 1.8 2004/02/27 02:55:17 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -190,6 +190,7 @@ struct RF_DagList_s {
RF_RaidAccessDesc_t *desc; /* ptr to descriptor for this access */
RF_AccTraceEntry_t tracerec; /* perf mon info for dags (not user
* info) */
+ struct RF_DagList_s *next; /* next DagList, if any */
};
/* convience macro for declaring a create dag function */
diff --git a/sys/dev/raidframe/rf_dagutils.c b/sys/dev/raidframe/rf_dagutils.c
index 584990b4821..4234a0d6e26 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.24 2004/01/10 17:04:44 oster Exp $ */
+/* $NetBSD: rf_dagutils.c,v 1.25 2004/02/27 02:55:17 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.24 2004/01/10 17:04:44 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_dagutils.c,v 1.25 2004/02/27 02:55:17 oster Exp $");
#include <dev/raidframe/raidframevar.h>
@@ -172,6 +172,12 @@ static struct pool rf_dagh_pool;
#define RF_DAGH_INC 16
#define RF_DAGH_INITIAL 32
+static struct pool rf_daglist_pool;
+#define RF_MAX_FREE_DAGLIST 128
+#define RF_DAGLIST_INITIAL 32
+
+
+
static void rf_ShutdownDAGs(void *);
static void
rf_ShutdownDAGs(void *ignored)
@@ -188,6 +194,12 @@ rf_ConfigureDAGs(RF_ShutdownList_t **listp)
"rf_dagh_pl", NULL);
pool_sethiwat(&rf_dagh_pool, RF_MAX_FREE_DAGH);
pool_prime(&rf_dagh_pool, RF_DAGH_INITIAL);
+
+ pool_init(&rf_daglist_pool, sizeof(RF_DagList_t), 0, 0, 0,
+ "rf_daglist_pl", NULL);
+ pool_sethiwat(&rf_daglist_pool, RF_MAX_FREE_DAGLIST);
+ pool_prime(&rf_daglist_pool, RF_DAGLIST_INITIAL);
+
rc = rf_ShutdownCreate(listp, rf_ShutdownDAGs, NULL);
if (rc) {
rf_print_unable_to_add_shutdown(__FILE__, __LINE__, rc);
@@ -214,6 +226,27 @@ rf_FreeDAGHeader(RF_DagHeader_t * dh)
{
pool_put(&rf_dagh_pool, dh);
}
+
+RF_DagList_t *
+rf_AllocDAGList()
+{
+ RF_DagList_t *dagList;
+
+ dagList = pool_get(&rf_daglist_pool, PR_WAITOK);
+ memset(dagList, 0, sizeof(RF_DagList_t));
+
+ return (dagList);
+}
+
+void
+rf_FreeDAGList(RF_DagList_t *dagList)
+{
+ pool_put(&rf_daglist_pool, dagList);
+}
+
+
+
+
/* allocates a buffer big enough to hold the data described by pda */
void *
rf_AllocBuffer(RF_Raid_t *raidPtr, RF_DagHeader_t *dag_h,
diff --git a/sys/dev/raidframe/rf_dagutils.h b/sys/dev/raidframe/rf_dagutils.h
index 62b7c6e5453..605918b71b2 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.7 2003/02/09 10:04:33 jdolecek Exp $ */
+/* $NetBSD: rf_dagutils.h,v 1.8 2004/02/27 02:55:17 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -68,6 +68,9 @@ RF_DagHeader_t *rf_AllocDAGHeader(void);
void rf_FreeDAGHeader(RF_DagHeader_t * dh);
+RF_DagList_t *rf_AllocDAGList(void);
+void rf_FreeDAGList(RF_DagList_t *);
+
void *rf_AllocBuffer(RF_Raid_t * raidPtr, RF_DagHeader_t * dag_h,
RF_PhysDiskAddr_t * pda,
RF_AllocListElem_t * allocList);
diff --git a/sys/dev/raidframe/rf_desc.h b/sys/dev/raidframe/rf_desc.h
index e7021c5388b..9e9aa3cfd64 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.9 2004/01/01 19:27:35 oster Exp $ */
+/* $NetBSD: rf_desc.h,v 1.10 2004/02/27 02:55:17 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -77,7 +77,7 @@ struct RF_RaidAccessDesc_s {
* RAID operation has gotten */
RF_AccessState_t *states; /* array of states to be run */
int status; /* pass/fail status of the last operation */
- RF_DagList_t *dagArray; /* array of dag lists, one list per stripe */
+ RF_DagList_t *dagList; /* list of dag lists, one list per stripe */
RF_AccessStripeMapHeader_t *asmap; /* the asm for this I/O */
void *bp; /* buf pointer for this RAID acc. ignored
* outside the kernel */
diff --git a/sys/dev/raidframe/rf_driver.c b/sys/dev/raidframe/rf_driver.c
index acaf0118c80..3b3f730b8b7 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.84 2004/01/15 20:27:27 oster Exp $ */
+/* $NetBSD: rf_driver.c,v 1.85 2004/02/27 02:55:17 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.84 2004/01/15 20:27:27 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.85 2004/02/27 02:55:17 oster Exp $");
#include "opt_raid_diagnostic.h"
@@ -209,7 +209,6 @@ rf_UnconfigureArray()
int
rf_Shutdown(RF_Raid_t *raidPtr)
{
-
if (!raidPtr->valid) {
RF_ERRORMSG("Attempt to shut down unconfigured RAIDframe driver. Aborting shutdown\n");
return (EINVAL);
@@ -288,7 +287,7 @@ int
rf_Configure(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr, RF_AutoConfig_t *ac)
{
RF_RowCol_t col;
- int rc;
+ int rc;
RF_LOCK_LKMGR_MUTEX(configureMutex);
configureCount++;
@@ -503,9 +502,18 @@ void
rf_FreeRaidAccDesc(RF_RaidAccessDesc_t *desc)
{
RF_Raid_t *raidPtr = desc->raidPtr;
+ RF_DagList_t *dagList, *temp;
RF_ASSERT(desc);
+ /* Cleanup the dagList(s) */
+ dagList = desc->dagList;
+ while(dagList != NULL) {
+ temp = dagList;
+ dagList = dagList->next;
+ rf_FreeDAGList(temp);
+ }
+
rf_FreeAllocList(desc->cleanupList);
pool_put(&rf_rad_pool, desc);
RF_LOCK_MUTEX(rf_rad_pool_lock);
diff --git a/sys/dev/raidframe/rf_states.c b/sys/dev/raidframe/rf_states.c
index 108711c57b4..01814a26e48 100644
--- a/sys/dev/raidframe/rf_states.c
+++ b/sys/dev/raidframe/rf_states.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_states.c,v 1.25 2004/01/02 21:41:08 oster Exp $ */
+/* $NetBSD: rf_states.c,v 1.26 2004/02/27 02:55:18 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_states.c,v 1.25 2004/01/02 21:41:08 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_states.c,v 1.26 2004/02/27 02:55:18 oster Exp $");
#include <sys/errno.h>
@@ -440,6 +440,7 @@ rf_State_CreateDAG(RF_RaidAccessDesc_t *desc)
RF_AccTraceEntry_t *tracerec = &desc->tracerec;
RF_Etimer_t timer;
RF_DagHeader_t *dag_h;
+ RF_DagList_t *dagList;
struct buf *bp;
int i, selectStatus;
@@ -449,9 +450,13 @@ rf_State_CreateDAG(RF_RaidAccessDesc_t *desc)
/* SelectAlgorithm returns one or more dags */
selectStatus = rf_SelectAlgorithm(desc, desc->flags | RF_DAG_SUPPRESS_LOCKS);
#if RF_DEBUG_VALIDATE_DAG
- if (rf_printDAGsDebug)
- for (i = 0; i < desc->numStripes; i++)
- rf_PrintDAGList(desc->dagArray[i].dags);
+ if (rf_printDAGsDebug) {
+ dagList = desc->dagList;
+ for (i = 0; i < desc->numStripes; i++) {
+ rf_PrintDAGList(dagList.dags);
+ dagList = dagList->next;
+ }
+ }
#endif /* RF_DEBUG_VALIDATE_DAG */
RF_ETIMER_STOP(timer);
RF_ETIMER_EVAL(timer);
@@ -476,13 +481,15 @@ rf_State_CreateDAG(RF_RaidAccessDesc_t *desc)
bp->b_error = EIO;
} else {
/* bind dags to desc */
+ dagList = desc->dagList;
for (i = 0; i < desc->numStripes; i++) {
- dag_h = desc->dagArray[i].dags;
+ dag_h = dagList->dags;
while (dag_h) {
dag_h->bp = (struct buf *) desc->bp;
dag_h->tracerec = tracerec;
dag_h = dag_h->next;
}
+ dagList = dagList->next;
}
desc->flags |= RF_DAG_DISPATCH_RETURNED;
desc->state++; /* next state should be rf_State_ExecuteDAG */
@@ -492,7 +499,7 @@ rf_State_CreateDAG(RF_RaidAccessDesc_t *desc)
-/* the access has an array of dagLists, one dagList per parity stripe.
+/* the access has an list of dagLists, one dagList per parity stripe.
* fire the first dag in each parity stripe (dagList).
* dags within a stripe (dagList) must be executed sequentially
* - this preserves atomic parity update
@@ -503,7 +510,7 @@ rf_State_ExecuteDAG(RF_RaidAccessDesc_t *desc)
{
int i;
RF_DagHeader_t *dag_h;
- RF_DagList_t *dagArray = desc->dagArray;
+ RF_DagList_t *dagList;
/* next state is always rf_State_ProcessDAG important to do
* this before firing the first dag (it may finish before we
@@ -512,16 +519,18 @@ rf_State_ExecuteDAG(RF_RaidAccessDesc_t *desc)
/* sweep dag array, a stripe at a time, firing the first dag
* in each stripe */
+ dagList = desc->dagList;
for (i = 0; i < desc->numStripes; i++) {
- RF_ASSERT(dagArray[i].numDags > 0);
- RF_ASSERT(dagArray[i].numDagsDone == 0);
- RF_ASSERT(dagArray[i].numDagsFired == 0);
- RF_ETIMER_START(dagArray[i].tracerec.timer);
+ RF_ASSERT(dagList->numDags > 0);
+ RF_ASSERT(dagList->numDagsDone == 0);
+ RF_ASSERT(dagList->numDagsFired == 0);
+ RF_ETIMER_START(dagList->tracerec.timer);
/* fire first dag in this stripe */
- dag_h = dagArray[i].dags;
+ dag_h = dagList->dags;
RF_ASSERT(dag_h);
- dagArray[i].numDagsFired++;
- rf_DispatchDAG(dag_h, (void (*) (void *)) rf_ContinueDagAccess, &dagArray[i]);
+ dagList->numDagsFired++;
+ rf_DispatchDAG(dag_h, (void (*) (void *)) rf_ContinueDagAccess, dagList);
+ dagList = dagList->next;
}
/* the DAG will always call the callback, even if there was no
@@ -542,21 +551,27 @@ rf_State_ProcessDAG(RF_RaidAccessDesc_t *desc)
RF_Raid_t *raidPtr = desc->raidPtr;
RF_DagHeader_t *dag_h;
int i, j, done = RF_TRUE;
- RF_DagList_t *dagArray = desc->dagArray;
+ RF_DagList_t *dagList, *temp;
RF_Etimer_t timer;
/* check to see if this is the last dag */
- for (i = 0; i < desc->numStripes; i++)
- if (dagArray[i].numDags != dagArray[i].numDagsDone)
+ dagList = desc->dagList;
+ for (i = 0; i < desc->numStripes; i++) {
+ if (dagList->numDags != dagList->numDagsDone)
done = RF_FALSE;
+ dagList = dagList->next;
+ }
if (done) {
if (desc->status) {
/* a dag failed, retry */
RF_ETIMER_START(timer);
/* free all dags */
+ dagList = desc->dagList;
for (i = 0; i < desc->numStripes; i++) {
- rf_FreeDAG(desc->dagArray[i].dags);
+ rf_FreeDAG(dagList->dags);
+ temp = dagList;
+ dagList = dagList->next;
}
rf_MarkFailuresInASMList(raidPtr, asmh);
/* back up to rf_State_CreateDAG */
@@ -572,20 +587,22 @@ rf_State_ProcessDAG(RF_RaidAccessDesc_t *desc)
/* see if any are ready to be fired. if so, fire them */
/* don't fire the initial dag in a list, it's fired in
* rf_State_ExecuteDAG */
+ dagList = desc->dagList;
for (i = 0; i < desc->numStripes; i++) {
- if ((dagArray[i].numDagsDone < dagArray[i].numDags)
- && (dagArray[i].numDagsDone == dagArray[i].numDagsFired)
- && (dagArray[i].numDagsFired > 0)) {
- RF_ETIMER_START(dagArray[i].tracerec.timer);
+ if ((dagList->numDagsDone < dagList->numDags)
+ && (dagList->numDagsDone == dagList->numDagsFired)
+ && (dagList->numDagsFired > 0)) {
+ RF_ETIMER_START(dagList->tracerec.timer);
/* fire next dag in this stripe */
/* first, skip to next dag awaiting execution */
- dag_h = dagArray[i].dags;
- for (j = 0; j < dagArray[i].numDagsDone; j++)
+ dag_h = dagList->dags;
+ for (j = 0; j < dagList->numDagsDone; j++)
dag_h = dag_h->next;
- dagArray[i].numDagsFired++;
+ dagList->numDagsFired++;
rf_DispatchDAG(dag_h, (void (*) (void *)) rf_ContinueDagAccess,
- &dagArray[i]);
+ dagList);
}
+ dagList = dagList->next;
}
return RF_TRUE;
}
@@ -598,6 +615,7 @@ rf_State_Cleanup(RF_RaidAccessDesc_t *desc)
RF_AccessStripeMapHeader_t *asmh = desc->asmap;
RF_Raid_t *raidPtr = desc->raidPtr;
RF_AccessStripeMap_t *asm_p;
+ RF_DagList_t *dagList;
RF_Etimer_t timer;
int i;
@@ -613,8 +631,10 @@ rf_State_Cleanup(RF_RaidAccessDesc_t *desc)
RF_ETIMER_START(timer);
/* free all dags */
+ dagList = desc->dagList;
for (i = 0; i < desc->numStripes; i++) {
- rf_FreeDAG(desc->dagArray[i].dags);
+ rf_FreeDAG(dagList->dags);
+ dagList = dagList->next;
}
RF_ETIMER_STOP(timer);
RF_ETIMER_EVAL(timer);