diff options
Diffstat (limited to 'sys/dev/raidframe/rf_revent.c')
-rw-r--r-- | sys/dev/raidframe/rf_revent.c | 336 |
1 files changed, 128 insertions, 208 deletions
diff --git a/sys/dev/raidframe/rf_revent.c b/sys/dev/raidframe/rf_revent.c index c4236962b64..e58736c7cd9 100644 --- a/sys/dev/raidframe/rf_revent.c +++ b/sys/dev/raidframe/rf_revent.c @@ -1,5 +1,5 @@ -/* $OpenBSD: rf_revent.c,v 1.1 1999/01/11 14:29:48 niklas Exp $ */ -/* $NetBSD: rf_revent.c,v 1.1 1998/11/13 04:20:34 oster Exp $ */ +/* $OpenBSD: rf_revent.c,v 1.2 1999/02/16 00:03:24 niklas Exp $ */ +/* $NetBSD: rf_revent.c,v 1.3 1999/02/05 00:06:17 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -29,61 +29,6 @@ /* * revent.c -- reconstruction event handling code */ -/* - * : - * Log: rf_revent.c,v - * Revision 1.22 1996/08/11 00:41:11 jimz - * extern hz only for kernel - * - * Revision 1.21 1996/07/15 05:40:41 jimz - * some recon datastructure cleanup - * better handling of multiple failures - * added undocumented double-recon test - * - * Revision 1.20 1996/06/17 03:18:04 jimz - * include shutdown.h for macroized ShutdownCreate - * - * Revision 1.19 1996/06/10 11:55:47 jimz - * Straightened out some per-array/not-per-array distinctions, fixed - * a couple bugs related to confusion. Added shutdown lists. Removed - * layout shutdown function (now subsumed by shutdown lists). - * - * Revision 1.18 1996/06/07 21:33:04 jimz - * begin using consistent types for sector numbers, - * stripe numbers, row+col numbers, recon unit numbers - * - * Revision 1.17 1996/06/05 18:06:02 jimz - * Major code cleanup. The Great Renaming is now done. - * Better modularity. Better typing. Fixed a bunch of - * synchronization bugs. Made a lot of global stuff - * per-desc or per-array. Removed dead code. - * - * Revision 1.16 1996/06/03 23:28:26 jimz - * more bugfixes - * check in tree to sync for IPDS runs with current bugfixes - * there still may be a problem with threads in the script test - * getting I/Os stuck- not trivially reproducible (runs ~50 times - * in a row without getting stuck) - * - * Revision 1.15 1996/05/30 12:59:18 jimz - * make etimer happier, more portable - * - * Revision 1.14 1996/05/20 16:13:40 jimz - * switch to rf_{mutex,cond}_{init,destroy} - * use RF_FREELIST for revents - * - * Revision 1.13 1996/05/18 20:09:47 jimz - * bit of cleanup to compile cleanly in kernel, once again - * - * Revision 1.12 1996/05/18 19:51:34 jimz - * major code cleanup- fix syntax, make some types consistent, - * add prototypes, clean out dead code, et cetera - * - */ - -#ifdef _KERNEL -#define KERNEL -#endif #include <sys/errno.h> @@ -101,206 +46,181 @@ static RF_FreeList_t *rf_revent_freelist; #define RF_REVENT_INITIAL 8 -#ifdef KERNEL #include <sys/proc.h> extern int hz; -#if !defined(__NetBSD__) && !defined(__OpenBSD__) -#define DO_WAIT(_rc) mpsleep(&(_rc)->eventQueue, PZERO, "raidframe eventq", 0, \ - (void *) simple_lock_addr((_rc)->eq_mutex), MS_LOCK_SIMPLE) -#else #define DO_WAIT(_rc) tsleep(&(_rc)->eventQueue, PRIBIO | PCATCH, "raidframe eventq", 0) -#endif #define DO_SIGNAL(_rc) wakeup(&(_rc)->eventQueue) -#else /* KERNEL */ - -#define DO_WAIT(_rc) RF_WAIT_COND((_rc)->eq_cond, (_rc)->eq_mutex) -#define DO_SIGNAL(_rc) RF_SIGNAL_COND((_rc)->eq_cond) - -#endif /* KERNEL */ static void rf_ShutdownReconEvent(void *); -static RF_ReconEvent_t *GetReconEventDesc(RF_RowCol_t row, RF_RowCol_t col, - void *arg, RF_Revent_t type); -RF_ReconEvent_t *rf_GetNextReconEvent(RF_RaidReconDesc_t *, - RF_RowCol_t, void (*continueFunc)(void *), - void *); +static RF_ReconEvent_t * +GetReconEventDesc(RF_RowCol_t row, RF_RowCol_t col, + void *arg, RF_Revent_t type); +RF_ReconEvent_t * +rf_GetNextReconEvent(RF_RaidReconDesc_t *, + RF_RowCol_t, void (*continueFunc) (void *), + void *); -static void rf_ShutdownReconEvent(ignored) - void *ignored; + static void rf_ShutdownReconEvent(ignored) + void *ignored; { - RF_FREELIST_DESTROY(rf_revent_freelist,next,(RF_ReconEvent_t *)); + RF_FREELIST_DESTROY(rf_revent_freelist, next, (RF_ReconEvent_t *)); } -int rf_ConfigureReconEvent(listp) - RF_ShutdownList_t **listp; +int +rf_ConfigureReconEvent(listp) + RF_ShutdownList_t **listp; { - int rc; - - RF_FREELIST_CREATE(rf_revent_freelist, RF_MAX_FREE_REVENT, - RF_REVENT_INC, sizeof(RF_ReconEvent_t)); - if (rf_revent_freelist == NULL) - return(ENOMEM); - rc = rf_ShutdownCreate(listp, rf_ShutdownReconEvent, NULL); - if (rc) { - RF_ERRORMSG3("Unable to add to shutdown list file %s line %d rc=%d\n", __FILE__, - __LINE__, rc); - rf_ShutdownReconEvent(NULL); - return(rc); - } - RF_FREELIST_PRIME(rf_revent_freelist, RF_REVENT_INITIAL,next, - (RF_ReconEvent_t *)); - return(0); + int rc; + + RF_FREELIST_CREATE(rf_revent_freelist, RF_MAX_FREE_REVENT, + RF_REVENT_INC, sizeof(RF_ReconEvent_t)); + if (rf_revent_freelist == NULL) + return (ENOMEM); + rc = rf_ShutdownCreate(listp, rf_ShutdownReconEvent, NULL); + if (rc) { + RF_ERRORMSG3("Unable to add to shutdown list file %s line %d rc=%d\n", __FILE__, + __LINE__, rc); + rf_ShutdownReconEvent(NULL); + return (rc); + } + RF_FREELIST_PRIME(rf_revent_freelist, RF_REVENT_INITIAL, next, + (RF_ReconEvent_t *)); + return (0); } - /* returns the next reconstruction event, blocking the calling thread until * one becomes available */ /* will now return null if it is blocked or will return an event if it is not */ -RF_ReconEvent_t *rf_GetNextReconEvent(reconDesc, row, continueFunc, continueArg) - RF_RaidReconDesc_t *reconDesc; - RF_RowCol_t row; - void (*continueFunc)(void *); - void *continueArg; +RF_ReconEvent_t * +rf_GetNextReconEvent(reconDesc, row, continueFunc, continueArg) + RF_RaidReconDesc_t *reconDesc; + RF_RowCol_t row; + void (*continueFunc) (void *); + void *continueArg; { - RF_Raid_t *raidPtr = reconDesc->raidPtr; - RF_ReconCtrl_t *rctrl = raidPtr->reconControl[row]; - RF_ReconEvent_t *event; - - RF_ASSERT( row >= 0 && row <= raidPtr->numRow ); - RF_LOCK_MUTEX(rctrl->eq_mutex); - RF_ASSERT( (rctrl->eventQueue==NULL) == (rctrl->eq_count == 0)); /* q null and count==0 must be equivalent conditions */ + RF_Raid_t *raidPtr = reconDesc->raidPtr; + RF_ReconCtrl_t *rctrl = raidPtr->reconControl[row]; + RF_ReconEvent_t *event; + RF_ASSERT(row >= 0 && row <= raidPtr->numRow); + RF_LOCK_MUTEX(rctrl->eq_mutex); + RF_ASSERT((rctrl->eventQueue == NULL) == (rctrl->eq_count == 0)); /* q null and count==0 + * must be equivalent + * conditions */ - rctrl->continueFunc=continueFunc; - rctrl->continueArg=continueArg; -#ifdef SIMULATE - if (!rctrl->eventQueue) { - RF_UNLOCK_MUTEX(rctrl->eq_mutex); - return (NULL); - } -#else /* SIMULATE */ + rctrl->continueFunc = continueFunc; + rctrl->continueArg = continueArg; -#ifdef KERNEL /* mpsleep timeout value: secs = timo_val/hz. 'ticks' here is defined as cycle-counter ticks, not softclock ticks */ -#define MAX_RECON_EXEC_TICKS 15000000 /* 150 Mhz => this many ticks in 100 ms */ +#define MAX_RECON_EXEC_TICKS 15000000 /* 150 Mhz => this many ticks in 100 + * ms */ #define RECON_DELAY_MS 25 #define RECON_TIMO ((RECON_DELAY_MS * hz) / 1000) - /* we are not pre-emptible in the kernel, but we don't want to run forever. If we run w/o blocking - * for more than MAX_RECON_EXEC_TICKS ticks of the cycle counter, delay for RECON_DELAY before continuing. - * this may murder us with context switches, so we may need to increase both the MAX...TICKS and the RECON_DELAY_MS. - */ - if (reconDesc->reconExecTimerRunning) { - int status; - - RF_ETIMER_STOP(reconDesc->recon_exec_timer); - RF_ETIMER_EVAL(reconDesc->recon_exec_timer); - reconDesc->reconExecTicks += RF_ETIMER_VAL_TICKS(reconDesc->recon_exec_timer); - if (reconDesc->reconExecTicks > reconDesc->maxReconExecTicks) - reconDesc->maxReconExecTicks = reconDesc->reconExecTicks; - if (reconDesc->reconExecTicks >= MAX_RECON_EXEC_TICKS) { - /* we've been running too long. delay for RECON_DELAY_MS */ + /* we are not pre-emptible in the kernel, but we don't want to run + * forever. If we run w/o blocking for more than MAX_RECON_EXEC_TICKS + * ticks of the cycle counter, delay for RECON_DELAY before + * continuing. this may murder us with context switches, so we may + * need to increase both the MAX...TICKS and the RECON_DELAY_MS. */ + if (reconDesc->reconExecTimerRunning) { + int status; + + RF_ETIMER_STOP(reconDesc->recon_exec_timer); + RF_ETIMER_EVAL(reconDesc->recon_exec_timer); + reconDesc->reconExecTicks += RF_ETIMER_VAL_TICKS(reconDesc->recon_exec_timer); + if (reconDesc->reconExecTicks > reconDesc->maxReconExecTicks) + reconDesc->maxReconExecTicks = reconDesc->reconExecTicks; + if (reconDesc->reconExecTicks >= MAX_RECON_EXEC_TICKS) { + /* we've been running too long. delay for + * RECON_DELAY_MS */ #if RF_RECON_STATS > 0 - reconDesc->numReconExecDelays++; -#endif /* RF_RECON_STATS > 0 */ -#if !defined(__NetBSD__) && !defined(__OpenBSD__) - status = mpsleep(&reconDesc->reconExecTicks, PZERO, "recon delay", RECON_TIMO, (void *) simple_lock_addr(rctrl->eq_mutex), MS_LOCK_SIMPLE); -#else - status = tsleep(&reconDesc->reconExecTicks, PRIBIO | PCATCH, "recon delay", RECON_TIMO ); -#endif - RF_ASSERT(status == EWOULDBLOCK); - reconDesc->reconExecTicks = 0; - } - } - -#endif /* KERNEL */ - - while (!rctrl->eventQueue) { + reconDesc->numReconExecDelays++; +#endif /* RF_RECON_STATS > 0 */ + status = tsleep(&reconDesc->reconExecTicks, PRIBIO | PCATCH, "recon delay", RECON_TIMO); + RF_ASSERT(status == EWOULDBLOCK); + reconDesc->reconExecTicks = 0; + } + } + while (!rctrl->eventQueue) { #if RF_RECON_STATS > 0 - reconDesc->numReconEventWaits++; -#endif /* RF_RECON_STATS > 0 */ - DO_WAIT(rctrl); -#ifdef KERNEL - reconDesc->reconExecTicks = 0; /* we've just waited */ -#endif /* KERNEL */ - } - -#endif /* SIMULATE */ - -#ifdef KERNEL - reconDesc->reconExecTimerRunning = 1; - RF_ETIMER_START(reconDesc->recon_exec_timer); -#endif /* KERNEL */ - - event = rctrl->eventQueue; - rctrl->eventQueue = event->next; - event->next = NULL; - rctrl->eq_count--; - RF_ASSERT( (rctrl->eventQueue==NULL) == (rctrl->eq_count == 0)); /* q null and count==0 must be equivalent conditions */ - RF_UNLOCK_MUTEX(rctrl->eq_mutex); - return(event); + reconDesc->numReconEventWaits++; +#endif /* RF_RECON_STATS > 0 */ + DO_WAIT(rctrl); + reconDesc->reconExecTicks = 0; /* we've just waited */ + } + + reconDesc->reconExecTimerRunning = 1; + RF_ETIMER_START(reconDesc->recon_exec_timer); + + event = rctrl->eventQueue; + rctrl->eventQueue = event->next; + event->next = NULL; + rctrl->eq_count--; + RF_ASSERT((rctrl->eventQueue == NULL) == (rctrl->eq_count == 0)); /* q null and count==0 + * must be equivalent + * conditions */ + RF_UNLOCK_MUTEX(rctrl->eq_mutex); + return (event); } - /* enqueues a reconstruction event on the indicated queue */ -void rf_CauseReconEvent(raidPtr, row, col, arg, type) - RF_Raid_t *raidPtr; - RF_RowCol_t row; - RF_RowCol_t col; - void *arg; - RF_Revent_t type; +void +rf_CauseReconEvent(raidPtr, row, col, arg, type) + RF_Raid_t *raidPtr; + RF_RowCol_t row; + RF_RowCol_t col; + void *arg; + RF_Revent_t type; { - RF_ReconCtrl_t *rctrl = raidPtr->reconControl[row]; - RF_ReconEvent_t *event = GetReconEventDesc(row, col, arg, type); - - if (type == RF_REVENT_BUFCLEAR) { - RF_ASSERT(col != rctrl->fcol); - } - - RF_ASSERT( row >= 0 && row <= raidPtr->numRow && col >=0 && col <= raidPtr->numCol ); - RF_LOCK_MUTEX(rctrl->eq_mutex); - RF_ASSERT( (rctrl->eventQueue==NULL) == (rctrl->eq_count == 0)); /* q null and count==0 must be equivalent conditions */ - event->next = rctrl->eventQueue; - rctrl->eventQueue = event; - rctrl->eq_count++; - RF_UNLOCK_MUTEX(rctrl->eq_mutex); - -#ifndef SIMULATE - DO_SIGNAL(rctrl); -#else /* !SIMULATE */ - (rctrl->continueFunc)(rctrl->continueArg); -#endif /* !SIMULATE */ + RF_ReconCtrl_t *rctrl = raidPtr->reconControl[row]; + RF_ReconEvent_t *event = GetReconEventDesc(row, col, arg, type); + + if (type == RF_REVENT_BUFCLEAR) { + RF_ASSERT(col != rctrl->fcol); + } + RF_ASSERT(row >= 0 && row <= raidPtr->numRow && col >= 0 && col <= raidPtr->numCol); + RF_LOCK_MUTEX(rctrl->eq_mutex); + RF_ASSERT((rctrl->eventQueue == NULL) == (rctrl->eq_count == 0)); /* q null and count==0 + * must be equivalent + * conditions */ + event->next = rctrl->eventQueue; + rctrl->eventQueue = event; + rctrl->eq_count++; + RF_UNLOCK_MUTEX(rctrl->eq_mutex); + + DO_SIGNAL(rctrl); } - /* allocates and initializes a recon event descriptor */ -static RF_ReconEvent_t *GetReconEventDesc(row, col, arg, type) - RF_RowCol_t row; - RF_RowCol_t col; - void *arg; - RF_Revent_t type; +static RF_ReconEvent_t * +GetReconEventDesc(row, col, arg, type) + RF_RowCol_t row; + RF_RowCol_t col; + void *arg; + RF_Revent_t type; { RF_ReconEvent_t *t; - RF_FREELIST_GET(rf_revent_freelist,t,next,(RF_ReconEvent_t *)); + RF_FREELIST_GET(rf_revent_freelist, t, next, (RF_ReconEvent_t *)); if (t == NULL) - return(NULL); + return (NULL); t->col = col; t->arg = arg; t->type = type; - return(t); + return (t); } -void rf_FreeReconEventDesc(event) - RF_ReconEvent_t *event; +void +rf_FreeReconEventDesc(event) + RF_ReconEvent_t *event; { - RF_FREELIST_FREE(rf_revent_freelist,event,next); + RF_FREELIST_FREE(rf_revent_freelist, event, next); } |