From 5e23bfcf9b79d15818f3789deae0c6cef8701d28 Mon Sep 17 00:00:00 2001 From: oster Date: Sun, 29 Feb 2004 01:24:34 +0000 Subject: [PATCH] Stripe functions are now handled by a linked-list instead of a runtime-variable array. Fix a bug where stripeFuncs was being freed, and then being used after (in the case of numStripesBailed > 0). --- sys/dev/raidframe/rf_aselect.c | 62 +++++++++++++++++++++------------ sys/dev/raidframe/rf_dagutils.c | 30 ++++++++++++++-- sys/dev/raidframe/rf_dagutils.h | 10 +++++- 3 files changed, 76 insertions(+), 26 deletions(-) diff --git a/sys/dev/raidframe/rf_aselect.c b/sys/dev/raidframe/rf_aselect.c index d62ab82f8896..6f0550db323b 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.12 2004/02/27 02:55:18 oster Exp $ */ +/* $NetBSD: rf_aselect.c,v 1.13 2004/02/29 01:24:34 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -33,7 +33,7 @@ *****************************************************************************/ #include -__KERNEL_RCSID(0, "$NetBSD: rf_aselect.c,v 1.12 2004/02/27 02:55:18 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_aselect.c,v 1.13 2004/02/29 01:24:34 oster Exp $"); #include @@ -55,7 +55,6 @@ static void TransferDagMemory(RF_DagHeader_t *, RF_DagHeader_t *); static int InitHdrNode(RF_DagHeader_t **, RF_Raid_t *); int rf_SelectAlgorithm(RF_RaidAccessDesc_t *, RF_RaidAccessFlags_t); - /****************************************************************************** * * Create and Initialiaze a dag header and termination node @@ -125,7 +124,7 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags) 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_FuncList_t *stripeFuncsList, *stripeFuncs, *stripeFuncsEnd, *temp; RF_AccessStripeMap_t *asm_up, *asm_bp; RF_AccessStripeMapHeader_t ***asmh_u, *endASMList; RF_AccessStripeMapHeader_t ***asmh_b; @@ -146,21 +145,26 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags) stripeUnitFuncs = NULL; blockFuncs = NULL; - /* get an array of dag-function creation pointers, try to avoid - * calling malloc */ - if (asm_h->numStripes <= MAXNSTRIPES) - stripeFuncs = normalStripeFuncs; - else - RF_Malloc(stripeFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr *)); + stripeFuncsList = NULL; + stripeFuncsEnd = NULL; /* walk through the asm list once collecting information */ /* attempt to find a single creation function for each stripe */ desc->numStripes = 0; for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) { desc->numStripes++; - (raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_p, &stripeFuncs[i]); + stripeFuncs = rf_AllocFuncList(); + + if (stripeFuncsEnd == NULL) { + stripeFuncsList = stripeFuncs; + } else { + stripeFuncsEnd->next = stripeFuncs; + } + stripeFuncsEnd = stripeFuncs; + + (raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_p, &(stripeFuncs->fp)); /* check to see if we found a creation func for this stripe */ - if (stripeFuncs[i] == (RF_VoidFuncPtr) NULL) { + if (stripeFuncs->fp == NULL) { /* could not find creation function for entire stripe * so, let's see if we can find one for each stripe * unit in the stripe */ @@ -250,12 +254,11 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags) if (cantCreateDAGs) { /* free memory and punt */ - if (asm_h->numStripes > MAXNSTRIPES) - RF_Free(stripeFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); if (numStripesBailed > 0) { stripeNum = 0; - for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) - if (stripeFuncs[i] == NULL) { + stripeFuncs = stripeFuncsList; + for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) { + if (stripeFuncs->fp == NULL) { numStripeUnits = asm_p->numStripeUnitsAccessed; for (j = 0; j < numStripeUnits; j++) rf_FreeAccessStripeMap(asmh_u[stripeNum][j]); @@ -263,10 +266,17 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags) RF_Free(stripeUnitFuncs[stripeNum], numStripeUnits * sizeof(RF_VoidFuncPtr)); stripeNum++; } + stripeFuncs = stripeFuncs->next; + } RF_ASSERT(stripeNum == numStripesBailed); RF_Free(stripeUnitFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); RF_Free(asmh_u, asm_h->numStripes * sizeof(RF_AccessStripeMapHeader_t **)); } + while (stripeFuncsList != NULL) { + temp = stripeFuncsList; + stripeFuncsList = stripeFuncsList->next; + rf_FreeFuncList(temp); + } desc->numStripes = 0; return (1); } else { @@ -278,6 +288,7 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags) dagListend = NULL; + stripeFuncs = stripeFuncsList; for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) { /* grab dag header for this stripe */ dag_h = NULL; @@ -294,7 +305,7 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags) dagList->desc = desc; - if (stripeFuncs[i] == (RF_VoidFuncPtr) NULL) { + if (stripeFuncs->fp == NULL) { /* use bailout functions for this stripe */ for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) { uFunc = stripeUnitFuncs[stripeNum][j]; @@ -349,15 +360,14 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags) } lastdag_h = tempdag_h; - (stripeFuncs[i]) (raidPtr, asm_p, tempdag_h, bp, flags, tempdag_h->allocList); + (stripeFuncs->fp) (raidPtr, asm_p, tempdag_h, bp, flags, tempdag_h->allocList); } dagList->dags = dag_h; + stripeFuncs = stripeFuncs->next; } RF_ASSERT(i == desc->numStripes); /* free memory */ - if (asm_h->numStripes > MAXNSTRIPES) - RF_Free(stripeFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); if ((numStripesBailed > 0) || (numStripeUnitsBailed > 0)) { stripeNum = 0; stripeUnitNum = 0; @@ -368,8 +378,9 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags) } else endASMList = NULL; /* walk through io, stripe by stripe */ - for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) - if (stripeFuncs[i] == NULL) { + stripeFuncs = stripeFuncsList; + for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) { + if (stripeFuncs->fp == NULL) { numStripeUnits = asm_p->numStripeUnitsAccessed; /* walk through stripe, stripe unit by * stripe unit */ @@ -403,6 +414,8 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags) RF_Free(stripeUnitFuncs[stripeNum], numStripeUnits * sizeof(RF_VoidFuncPtr)); stripeNum++; } + stripeFuncs = stripeFuncs->next; + } RF_ASSERT(stripeNum == numStripesBailed); RF_Free(stripeUnitFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); RF_Free(asmh_u, asm_h->numStripes * sizeof(RF_AccessStripeMapHeader_t **)); @@ -412,6 +425,11 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags) RF_Free(asmh_b, raidPtr->Layout.numDataCol * asm_h->numStripes * sizeof(RF_AccessStripeMapHeader_t **)); } } + while (stripeFuncsList != NULL) { + temp = stripeFuncsList; + stripeFuncsList = stripeFuncsList->next; + rf_FreeFuncList(temp); + } return (0); } } diff --git a/sys/dev/raidframe/rf_dagutils.c b/sys/dev/raidframe/rf_dagutils.c index c33303ae56f6..bb6a730d136f 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.26 2004/02/27 03:18:02 oster Exp $ */ +/* $NetBSD: rf_dagutils.c,v 1.27 2004/02/29 01:24:34 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -33,7 +33,7 @@ *****************************************************************************/ #include -__KERNEL_RCSID(0, "$NetBSD: rf_dagutils.c,v 1.26 2004/02/27 03:18:02 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_dagutils.c,v 1.27 2004/02/29 01:24:34 oster Exp $"); #include @@ -176,7 +176,9 @@ static struct pool rf_daglist_pool; #define RF_MAX_FREE_DAGLIST 128 #define RF_DAGLIST_INITIAL 32 - +static struct pool rf_funclist_pool; +#define RF_MAX_FREE_FUNCLIST 128 +#define RF_FUNCLIST_INITIAL 32 static void rf_ShutdownDAGs(void *); static void @@ -184,6 +186,7 @@ rf_ShutdownDAGs(void *ignored) { pool_destroy(&rf_dagh_pool); pool_destroy(&rf_daglist_pool); + pool_destroy(&rf_funclist_pool); } int @@ -200,6 +203,11 @@ rf_ConfigureDAGs(RF_ShutdownList_t **listp) "rf_daglist_pl", NULL); pool_sethiwat(&rf_daglist_pool, RF_MAX_FREE_DAGLIST); pool_prime(&rf_daglist_pool, RF_DAGLIST_INITIAL); + + pool_init(&rf_funclist_pool, sizeof(RF_FuncList_t), 0, 0, 0, + "rf_funcist_pl", NULL); + pool_sethiwat(&rf_funclist_pool, RF_MAX_FREE_FUNCLIST); + pool_prime(&rf_funclist_pool, RF_FUNCLIST_INITIAL); rc = rf_ShutdownCreate(listp, rf_ShutdownDAGs, NULL); if (rc) { @@ -245,6 +253,22 @@ rf_FreeDAGList(RF_DagList_t *dagList) pool_put(&rf_daglist_pool, dagList); } +RF_FuncList_t * +rf_AllocFuncList() +{ + RF_FuncList_t *funcList; + + funcList = pool_get(&rf_funclist_pool, PR_WAITOK); + memset(funcList, 0, sizeof(RF_FuncList_t)); + + return (funcList); +} + +void +rf_FreeFuncList(RF_FuncList_t *funcList) +{ + pool_put(&rf_funclist_pool, funcList); +} diff --git a/sys/dev/raidframe/rf_dagutils.h b/sys/dev/raidframe/rf_dagutils.h index 605918b71b27..7f17ed9bbe69 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.8 2004/02/27 02:55:17 oster Exp $ */ +/* $NetBSD: rf_dagutils.h,v 1.9 2004/02/29 01:24:34 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -48,6 +48,11 @@ struct RF_RedFuncs_s { char *SimpleName; }; +typedef struct RF_FuncList_s { + RF_VoidFuncPtr fp; + struct RF_FuncList_s *next; +} RF_FuncList_t; + extern const RF_RedFuncs_t rf_xorFuncs; extern const RF_RedFuncs_t rf_xorRecoveryFuncs; @@ -71,6 +76,9 @@ void rf_FreeDAGHeader(RF_DagHeader_t * dh); RF_DagList_t *rf_AllocDAGList(void); void rf_FreeDAGList(RF_DagList_t *); +RF_FuncList_t *rf_AllocFuncList(void); +void rf_FreeFuncList(RF_FuncList_t *); + void *rf_AllocBuffer(RF_Raid_t * raidPtr, RF_DagHeader_t * dag_h, RF_PhysDiskAddr_t * pda, RF_AllocListElem_t * allocList);