diff options
author | Peter Galbavy <peter@cvs.openbsd.org> | 1999-08-03 13:56:39 +0000 |
---|---|---|
committer | Peter Galbavy <peter@cvs.openbsd.org> | 1999-08-03 13:56:39 +0000 |
commit | e4ad7ec5153f083d6c217951f62c45f7b5bef1bf (patch) | |
tree | 534f382aaaf300943319bc2085376472d570447e /sys/dev | |
parent | 770ef6ff81279f6a89955b304db960c0cd5aa562 (diff) |
* rf_reconstruct.c: adopt nilkas' suggestion regard statics and
__inline__ - this is a proof of concept and will cover the raidframe
source as a whole over coming updates. Update namespace of function to
prefix with rf_ - comments again welcome.
* overall: rework the macros in rf_etimer.h and the resultant changes
to their use to count microseconds and not clock ticks. Restore the code
in rf_revent.c to a similar strcuture to before the previous commit,
and use the system timers to govern resource usage.
Tested with local i386/IDE and the reconstruction of a disk in my
array - performance has improved for reconstruction at no noticable
CPU cost.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/raidframe/rf_desc.h | 6 | ||||
-rw-r--r-- | sys/dev/raidframe/rf_driver.c | 8 | ||||
-rw-r--r-- | sys/dev/raidframe/rf_etimer.h | 69 | ||||
-rw-r--r-- | sys/dev/raidframe/rf_openbsdkintf.c | 4 | ||||
-rw-r--r-- | sys/dev/raidframe/rf_reconstruct.c | 218 | ||||
-rw-r--r-- | sys/dev/raidframe/rf_revent.c | 53 | ||||
-rw-r--r-- | sys/dev/raidframe/rf_sys.c | 13 | ||||
-rw-r--r-- | sys/dev/raidframe/rf_utils.h | 3 |
8 files changed, 163 insertions, 211 deletions
diff --git a/sys/dev/raidframe/rf_desc.h b/sys/dev/raidframe/rf_desc.h index b76466f298a..1a1be3ded7f 100644 --- a/sys/dev/raidframe/rf_desc.h +++ b/sys/dev/raidframe/rf_desc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rf_desc.h,v 1.2 1999/02/16 00:02:38 niklas Exp $ */ +/* $OpenBSD: rf_desc.h,v 1.3 1999/08/03 13:56:37 peter Exp $ */ /* $NetBSD: rf_desc.h,v 1.4 1999/02/05 00:06:09 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. @@ -54,8 +54,8 @@ struct RF_RaidReconDesc_s { */ RF_Etimer_t recon_exec_timer; RF_uint64 reconExecTimerRunning; - RF_uint64 reconExecTicks; - RF_uint64 maxReconExecTicks; + RF_uint64 reconExecuSecs; + RF_uint64 maxReconExecuSecs; #if RF_RECON_STATS > 0 RF_uint64 hsStallCount; /* head sep stall count */ diff --git a/sys/dev/raidframe/rf_driver.c b/sys/dev/raidframe/rf_driver.c index 5581cbfd316..887d16d44c2 100644 --- a/sys/dev/raidframe/rf_driver.c +++ b/sys/dev/raidframe/rf_driver.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rf_driver.c,v 1.3 1999/07/30 14:45:32 peter Exp $ */ +/* $OpenBSD: rf_driver.c,v 1.4 1999/08/03 13:56:37 peter Exp $ */ /* $NetBSD: rf_driver.c,v 1.12 1999/07/19 01:36:07 oster Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -964,8 +964,6 @@ rf_ConfigureDebug(cfgPtr) } /* performance monitoring stuff */ -#define TIMEVAL_TO_US(t) (((long) t.tv_sec) * 1000000L + (long) t.tv_usec) - #if !defined(_KERNEL) && !defined(SIMULATE) /* @@ -1014,7 +1012,7 @@ rf_StopThroughputStats(RF_Raid_t * raidPtr) if (raidPtr->throughputstats.num_out_ios == 0) { RF_GETTIME(raidPtr->throughputstats.stop); RF_TIMEVAL_DIFF(&raidPtr->throughputstats.start, &raidPtr->throughputstats.stop, &diff); - raidPtr->throughputstats.sum_io_us += TIMEVAL_TO_US(diff); + raidPtr->throughputstats.sum_io_us += RF_TIMEVAL_TO_US(diff); } RF_UNLOCK_MUTEX(raidPtr->throughputstats.mutex); } @@ -1063,7 +1061,7 @@ rf_PrintUserStats(RF_Raid_t * raidPtr) struct timeval diff; RF_TIMEVAL_DIFF(&raidPtr->userstats.start, &raidPtr->userstats.stop, &diff); - elapsed_us = TIMEVAL_TO_US(diff); + elapsed_us = RF_TIMEVAL_TO_US(diff); /* 2000 sectors per megabyte, 10000000 microseconds per second */ if (elapsed_us) diff --git a/sys/dev/raidframe/rf_etimer.h b/sys/dev/raidframe/rf_etimer.h index 2033b9b46c6..826744a316f 100644 --- a/sys/dev/raidframe/rf_etimer.h +++ b/sys/dev/raidframe/rf_etimer.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rf_etimer.h,v 1.2 1999/02/16 00:02:43 niklas Exp $ */ +/* $OpenBSD: rf_etimer.h,v 1.3 1999/08/03 13:56:37 peter Exp $ */ /* $NetBSD: rf_etimer.h,v 1.3 1999/02/05 00:06:11 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. @@ -27,57 +27,44 @@ * rights to redistribute these changes. */ -/* rf_etimer.h -- header file for code related to accurate timing - * This code currently assumes that the elapsed time between START_TIMER - * and START_TIMER is less than the period of the cycle counter. This - * means the events you want to time must be less than: - * clock speed max time - * ---------- -------- - * 175 MHz 24 sec - * 150 MHz 28 sec - * 125 MHz 34 sec - * - * - */ - - #ifndef _RF__RF_TIMER_H_ #define _RF__RF_TIMER_H_ #include "rf_options.h" +#include "rf_utils.h" -extern unsigned int rpcc(void); -#define rf_read_cycle_counter rpcc - -#define RF_DEF_TIMER_MAX_VAL 0xFFFFFFFF - -typedef struct RF_EtimerVal_s { - unsigned ccnt; /* cycle count */ -} RF_EtimerVal_t; +#include <sys/time.h> +#include <sys/kernel.h> struct RF_Etimer_s { - RF_EtimerVal_t st; - RF_EtimerVal_t et; - unsigned long ticks; /* elapsed time in ticks */ + struct timeval st; + struct timeval et; + struct timeval diff; }; -extern long rf_timer_max_val; -extern long rf_timer_ticks_per_second; -extern unsigned long rf_timer_ticks_per_usec; +#define RF_ETIMER_START(_t_) \ + { \ + int s; \ + bzero(&(_t_), sizeof (_t_)); \ + s = splclock(); \ + (_t_).st = mono_time; \ + splx(s); \ + } -#define RF_ETIMER_TICKS2US(_tcks_) ( (_tcks_) / rf_timer_ticks_per_usec ) -#define RF_ETIMER_START(_t_) { (_t_).st.ccnt = rf_read_cycle_counter(); } -#define RF_ETIMER_STOP(_t_) { (_t_).et.ccnt = rf_read_cycle_counter(); } -#define RF_ETIMER_EVAL(_t_) { \ - if ((_t_).st.ccnt < (_t_).et.ccnt) \ - (_t_).ticks = (_t_).et.ccnt - (_t_).st.ccnt; \ - else \ - (_t_).ticks = rf_timer_max_val - ((_t_).st.ccnt - (_t_).et.ccnt); \ -} +#define RF_ETIMER_STOP(_t_) \ + { \ + int s; \ + s = splclock(); \ + (_t_).et = mono_time; \ + splx(s); \ + } -#define RF_ETIMER_VAL_TICKS(_t_) ((_t_).ticks) -#define RF_ETIMER_VAL_US(_t_) (RF_ETIMER_TICKS2US((_t_).ticks)) -#define RF_ETIMER_VAL_MS(_t_) (RF_ETIMER_TICKS2US((_t_).ticks)/1000) +#define RF_ETIMER_EVAL(_t_) \ + { \ + RF_TIMEVAL_DIFF(&(_t_).st, &(_t_).et, &(_t_).diff) \ + } +#define RF_ETIMER_VAL_US(_t_) (RF_TIMEVAL_TO_US((_t_).diff)) +#define RF_ETIMER_VAL_MS(_t_) (RF_TIMEVAL_TO_US((_t_).diff)/1000) #endif /* !_RF__RF_TIMER_H_ */ diff --git a/sys/dev/raidframe/rf_openbsdkintf.c b/sys/dev/raidframe/rf_openbsdkintf.c index 5fb78c3075f..ff33560b7a3 100644 --- a/sys/dev/raidframe/rf_openbsdkintf.c +++ b/sys/dev/raidframe/rf_openbsdkintf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rf_openbsdkintf.c,v 1.5 1999/08/02 20:32:49 peter Exp $ */ +/* $OpenBSD: rf_openbsdkintf.c,v 1.6 1999/08/03 13:56:37 peter Exp $ */ /*- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. @@ -1814,6 +1814,7 @@ rf_InitBP(bp, b_vp, rw_flag, dev, startSect, numSect, buf, cbFunc, cbArg, /* Extras... */ +#if 0 unsigned int rpcc() { @@ -1823,7 +1824,6 @@ rpcc() return (0); } -#if 0 int rf_GetSpareTableFromDaemon(req) RF_SparetWait_t *req; diff --git a/sys/dev/raidframe/rf_reconstruct.c b/sys/dev/raidframe/rf_reconstruct.c index 75fd5d75a03..a1263674809 100644 --- a/sys/dev/raidframe/rf_reconstruct.c +++ b/sys/dev/raidframe/rf_reconstruct.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rf_reconstruct.c,v 1.3 1999/07/30 14:45:33 peter Exp $ */ +/* $OpenBSD: rf_reconstruct.c,v 1.4 1999/08/03 13:56:37 peter Exp $ */ /* $NetBSD: rf_reconstruct.c,v 1.5 1999/03/02 03:18:49 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. @@ -68,6 +68,12 @@ #include "rf_kintf.h" +#if defined(__GNUC__) && !defined(DDB) +#define INTEGRATE static __inline__ +#else +#define INTEGRATE +#endif + /* setting these to -1 causes them to be set to their default values if not set by debug options */ #define Dprintf(s) if (rf_reconDebug) rf_debug_printf(s,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL) @@ -96,41 +102,26 @@ static RF_FreeList_t *rf_recond_freelist; #define RF_MAX_FREE_RECOND 4 #define RF_RECOND_INC 1 -static RF_RaidReconDesc_t * -AllocRaidReconDesc(RF_Raid_t * raidPtr, - RF_RowCol_t row, RF_RowCol_t col, RF_RaidDisk_t * spareDiskPtr, - int numDisksDone, RF_RowCol_t srow, RF_RowCol_t scol); -static void FreeReconDesc(RF_RaidReconDesc_t * reconDesc); -static int -ProcessReconEvent(RF_Raid_t * raidPtr, RF_RowCol_t frow, - RF_ReconEvent_t * event); -static int -IssueNextReadRequest(RF_Raid_t * raidPtr, RF_RowCol_t row, - RF_RowCol_t col); -static int TryToRead(RF_Raid_t * raidPtr, RF_RowCol_t row, RF_RowCol_t col); -static int -ComputePSDiskOffsets(RF_Raid_t * raidPtr, RF_StripeNum_t psid, - RF_RowCol_t row, RF_RowCol_t col, RF_SectorNum_t * outDiskOffset, - RF_SectorNum_t * outFailedDiskSectorOffset, RF_RowCol_t * spRow, - RF_RowCol_t * spCol, RF_SectorNum_t * spOffset); -static int IssueNextWriteRequest(RF_Raid_t * raidPtr, RF_RowCol_t row); -static int ReconReadDoneProc(void *arg, int status); -static int ReconWriteDoneProc(void *arg, int status); -static void -CheckForNewMinHeadSep(RF_Raid_t * raidPtr, RF_RowCol_t row, - RF_HeadSepLimit_t hsCtr); -static int -CheckHeadSeparation(RF_Raid_t * raidPtr, RF_PerDiskReconCtrl_t * ctrl, - RF_RowCol_t row, RF_RowCol_t col, RF_HeadSepLimit_t hsCtr, - RF_ReconUnitNum_t which_ru); -static int -CheckForcedOrBlockedReconstruction(RF_Raid_t * raidPtr, - RF_ReconParityStripeStatus_t * pssPtr, RF_PerDiskReconCtrl_t * ctrl, - RF_RowCol_t row, RF_RowCol_t col, RF_StripeNum_t psid, - RF_ReconUnitNum_t which_ru); -static void ForceReconReadDoneProc(void *arg, int status); - -static void rf_ShutdownReconstruction(void *); +RF_RaidReconDesc_t *rf_AllocRaidReconDesc __P((RF_Raid_t *, RF_RowCol_t, RF_RowCol_t, RF_RaidDisk_t *, int, RF_RowCol_t, RF_RowCol_t)); +int rf_ProcessReconEvent __P((RF_Raid_t *, RF_RowCol_t, RF_ReconEvent_t *)); +int rf_IssueNextReadRequest __P((RF_Raid_t *, RF_RowCol_t, RF_RowCol_t)); +int rf_TryToRead __P((RF_Raid_t *, RF_RowCol_t, RF_RowCol_t)); +int rf_ComputePSDiskOffsets __P((RF_Raid_t *, RF_StripeNum_t, RF_RowCol_t, RF_RowCol_t, RF_SectorNum_t *, RF_SectorNum_t *, RF_RowCol_t *, RF_RowCol_t *, RF_SectorNum_t *)); +int rf_ReconReadDoneProc(void *, int); +int rf_ReconWriteDoneProc(void *, int); +void rf_CheckForNewMinHeadSep(RF_Raid_t *, RF_RowCol_t, RF_HeadSepLimit_t); +int rf_CheckHeadSeparation(RF_Raid_t *, RF_PerDiskReconCtrl_t *, RF_RowCol_t, RF_RowCol_t, RF_HeadSepLimit_t, RF_ReconUnitNum_t); +void rf_ForceReconReadDoneProc __P((void *, int)); +void rf_ShutdownReconstruction __P((void *)); + +/* + * these functions are inlined on gcc. If they are used more than + * once, it is strongly advised to un-line them + */ +INTEGRATE void rf_FreeReconDesc __P((RF_RaidReconDesc_t *)); +INTEGRATE int rf_IssueNextWriteRequest __P((RF_Raid_t *, RF_RowCol_t)); +INTEGRATE int rf_CheckForcedOrBlockedReconstruction __P((RF_Raid_t *, RF_ReconParityStripeStatus_t *, RF_PerDiskReconCtrl_t *, RF_RowCol_t, RF_RowCol_t, RF_StripeNum_t, RF_ReconUnitNum_t)); +INTEGRATE void rf_SignalReconDone __P((RF_Raid_t *)); /* XXX these should be in a .h file somewhere */ int raidlookup __P((char *, struct proc *, struct vnode **)); @@ -147,8 +138,8 @@ static RF_FreeList_t *rf_rdp_freelist; #define RF_MAX_FREE_RDP 4 #define RF_RDP_INC 1 -static void -SignalReconDone(RF_Raid_t * raidPtr) +INTEGRATE void +rf_SignalReconDone(RF_Raid_t * raidPtr) { RF_ReconDoneProc_t *p; @@ -190,7 +181,7 @@ rf_RegisterReconDoneProc( * in the kernel, we fire off the recon thread. * ****************************************************************************************/ -static void +void rf_ShutdownReconstruction(ignored) void *ignored; { @@ -228,8 +219,8 @@ rf_ConfigureReconstruction(listp) return (0); } -static RF_RaidReconDesc_t * -AllocRaidReconDesc(raidPtr, row, col, spareDiskPtr, numDisksDone, srow, scol) +RF_RaidReconDesc_t * +rf_AllocRaidReconDesc(raidPtr, row, col, spareDiskPtr, numDisksDone, srow, scol) RF_Raid_t *raidPtr; RF_RowCol_t row; RF_RowCol_t col; @@ -256,29 +247,31 @@ AllocRaidReconDesc(raidPtr, row, col, spareDiskPtr, numDisksDone, srow, scol) return (reconDesc); } -static void -FreeReconDesc(reconDesc) +INTEGRATE void +rf_FreeReconDesc(reconDesc) RF_RaidReconDesc_t *reconDesc; { #if RF_RECON_STATS > 0 - printf("RAIDframe: %lu recon event waits, %lu recon delays\n", - (long) reconDesc->numReconEventWaits, (long) reconDesc->numReconExecDelays); -#endif /* RF_RECON_STATS > 0 */ - printf("RAIDframe: %lu max exec ticks\n", - (long) reconDesc->maxReconExecTicks); + printf("RAIDframe: %qu recon event waits, %qu recon delays\n", + reconDesc->numReconEventWaits, reconDesc->numReconExecDelays); +#endif /* RF_RECON_STATS > 0 */ + + printf("RAIDframe: %qu max exec uSec\n", reconDesc->maxReconExecuSecs); + #if (RF_RECON_STATS > 0) || defined(KERNEL) printf("\n"); -#endif /* (RF_RECON_STATS > 0) || KERNEL */ +#endif /* (RF_RECON_STATS > 0) || KERNEL */ RF_FREELIST_FREE(rf_recond_freelist, reconDesc, next); } -/***************************************************************************************** +/*********************************************************************** * * primary routine to reconstruct a failed disk. This should be called from * within its own thread. It won't return until reconstruction completes, * fails, or is aborted. - ****************************************************************************************/ + * + ***********************************************************************/ int rf_ReconstructFailedDisk(raidPtr, row, col) RF_Raid_t *raidPtr; @@ -360,7 +353,7 @@ rf_ReconstructFailedDiskBasic(raidPtr, row, col) } RF_UNLOCK_MUTEX(raidPtr->mutex); - reconDesc = AllocRaidReconDesc((void *) raidPtr, row, col, spareDiskPtr, numDisksDone, srow, scol); + reconDesc = rf_AllocRaidReconDesc((void *) raidPtr, row, col, spareDiskPtr, numDisksDone, srow, scol); raidPtr->reconDesc = (void *) reconDesc; #if RF_RECON_STATS > 0 reconDesc->hsStallCount = 0; @@ -368,8 +361,8 @@ rf_ReconstructFailedDiskBasic(raidPtr, row, col) reconDesc->numReconEventWaits = 0; #endif /* RF_RECON_STATS > 0 */ reconDesc->reconExecTimerRunning = 0; - reconDesc->reconExecTicks = 0; - reconDesc->maxReconExecTicks = 0; + reconDesc->reconExecuSecs = 0; + reconDesc->maxReconExecuSecs = 0; rc = rf_ContinueReconstructFailedDisk(reconDesc); if (!rc) { @@ -497,7 +490,7 @@ rf_ReconstructInPlace(raidPtr, row, col) first time. Close it before trying to open it again.. */ if (raidPtr->raid_cinfo[row][col].ci_vp != NULL) { - printf("Closed the open device: %s\n", + printf("Closing the open device: %s\n", raidPtr->Disks[row][col].devname); VOP_UNLOCK(raidPtr->raid_cinfo[row][col].ci_vp, 0, proc); (void) vn_close(raidPtr->raid_cinfo[row][col].ci_vp, @@ -511,7 +504,8 @@ rf_ReconstructInPlace(raidPtr, row, col) proc, &vp); if (retcode) { - printf("raid%d: rebuilding: raidlookup on device: %s failed: %d!\n",raidPtr->raidid, + printf("raid%d: rebuilding: raidlookup on device: %s failed: %d!\n", + raidPtr->raidid, raidPtr->Disks[row][col].devname, retcode); /* XXX the component isn't responding properly... @@ -569,7 +563,7 @@ rf_ReconstructInPlace(raidPtr, row, col) RF_UNLOCK_MUTEX(raidPtr->mutex); - reconDesc = AllocRaidReconDesc((void *) raidPtr, row, col, + reconDesc = rf_AllocRaidReconDesc((void *) raidPtr, row, col, spareDiskPtr, numDisksDone, row, col); raidPtr->reconDesc = (void *) reconDesc; @@ -579,8 +573,8 @@ rf_ReconstructInPlace(raidPtr, row, col) reconDesc->numReconEventWaits = 0; #endif /* RF_RECON_STATS > 0 */ reconDesc->reconExecTimerRunning = 0; - reconDesc->reconExecTicks = 0; - reconDesc->maxReconExecTicks = 0; + reconDesc->reconExecuSecs = 0; + reconDesc->maxReconExecuSecs = 0; rc = rf_ContinueReconstructFailedDisk(reconDesc); } else { RF_ERRORMSG1("RECON: no way to reconstruct failed disk for arch %c\n", @@ -642,10 +636,7 @@ rf_ContinueReconstructFailedDisk(reconDesc) int retcode, i, ds; switch (reconDesc->state) { - - case 0: - raidPtr->accumXorTimeUs = 0; /* create one trace record per physical disk */ @@ -661,11 +652,8 @@ rf_ContinueReconstructFailedDisk(reconDesc) Dprintf("RECON: end request suspend\n"); rf_StartUserStats(raidPtr); /* zero out the stats kept on * user accs */ - /* fall through to state 1 */ - case 1: - RF_LOCK_MUTEX(raidPtr->mutex); /* create the reconstruction control pointer and install it in @@ -689,13 +677,15 @@ rf_ContinueReconstructFailedDisk(reconDesc) if (i != col) { /* find and issue the next I/O on the * indicated disk */ - if (IssueNextReadRequest(raidPtr, row, i)) { + if (rf_IssueNextReadRequest(raidPtr, row, i)) { Dprintf2("RECON: done issuing for r%d c%d\n", row, i); reconDesc->numDisksDone++; } } } + reconDesc->state = 2; + case 2: Dprintf("RECON: resume requests\n"); rf_ResumeNewRequests(raidPtr); @@ -709,14 +699,12 @@ rf_ContinueReconstructFailedDisk(reconDesc) * they've completed all work */ mapPtr = raidPtr->reconControl[row]->reconMap; - - while (reconDesc->numDisksDone < raidPtr->numCol - 1) { event = rf_GetNextReconEvent(reconDesc, row, (void (*) (void *)) rf_ContinueReconstructFailedDisk, reconDesc); RF_ASSERT(event); - if (ProcessReconEvent(raidPtr, row, event)) + if (rf_ProcessReconEvent(raidPtr, row, event)) reconDesc->numDisksDone++; raidPtr->reconControl[row]->percentComplete = 100 - (rf_UnitsLeftToReconstruct(mapPtr) * 100 / mapPtr->totalRUs); if (rf_prReconSched) { @@ -724,11 +712,8 @@ rf_ContinueReconstructFailedDisk(reconDesc) } } - - reconDesc->state = 4; - case 4: mapPtr = raidPtr->reconControl[row]->reconMap; if (rf_reconDebug) { @@ -742,7 +727,7 @@ rf_ContinueReconstructFailedDisk(reconDesc) event = rf_GetNextReconEvent(reconDesc, row, (void (*) (void *)) rf_ContinueReconstructFailedDisk, reconDesc); RF_ASSERT(event); - (void) ProcessReconEvent(raidPtr, row, event); /* ignore return code */ + (void) rf_ProcessReconEvent(raidPtr, row, event); /* ignore return code */ raidPtr->reconControl[row]->percentComplete = 100 - (rf_UnitsLeftToReconstruct(mapPtr) * 100 / mapPtr->totalRUs); if (rf_prReconSched) { rf_PrintReconSchedule(raidPtr->reconControl[row]->reconMap, &(raidPtr->reconControl[row]->starttime)); @@ -758,8 +743,6 @@ rf_ContinueReconstructFailedDisk(reconDesc) * user accesses when we free up the psstatus structure as * part of FreeReconControl() */ - - reconDesc->state = 6; retcode = rf_SuspendNewRequestsAndWait(raidPtr); @@ -770,9 +753,6 @@ rf_ContinueReconstructFailedDisk(reconDesc) /* fall through to state 6 */ case 6: - - - RF_LOCK_MUTEX(raidPtr->mutex); raidPtr->numFailures--; ds = (raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE); @@ -807,19 +787,19 @@ rf_ContinueReconstructFailedDisk(reconDesc) #endif /* RF_RECON_STATS > 0 */ rf_FreeReconControl(raidPtr, row); RF_Free(raidPtr->recon_tracerecs, raidPtr->numCol * sizeof(RF_AccTraceEntry_t)); - FreeReconDesc(reconDesc); + rf_FreeReconDesc(reconDesc); } - SignalReconDone(raidPtr); + rf_SignalReconDone(raidPtr); return (0); } /***************************************************************************************** * do the right thing upon each reconstruction event. * returns nonzero if and only if there is nothing left unread on the indicated disk ****************************************************************************************/ -static int -ProcessReconEvent(raidPtr, frow, event) +int +rf_ProcessReconEvent(raidPtr, frow, event) RF_Raid_t *raidPtr; RF_RowCol_t frow; RF_ReconEvent_t *event; @@ -828,7 +808,7 @@ ProcessReconEvent(raidPtr, frow, event) RF_ReconBuffer_t *rbuf; RF_SectorCount_t sectorsPerRU; - Dprintf1("RECON: ProcessReconEvent type %d\n", event->type); + Dprintf1("RECON: rf_ProcessReconEvent type %d\n", event->type); switch (event->type) { /* a read I/O has completed */ @@ -843,7 +823,7 @@ ProcessReconEvent(raidPtr, frow, event) submitblocked = rf_SubmitReconBuffer(rbuf, 0, 0); Dprintf1("RECON: submitblocked=%d\n", submitblocked); if (!submitblocked) - retcode = IssueNextReadRequest(raidPtr, frow, event->col); + retcode = rf_IssueNextReadRequest(raidPtr, frow, event->col); break; /* a write I/O has completed */ @@ -879,26 +859,26 @@ ProcessReconEvent(raidPtr, frow, event) RF_ASSERT(!submitblocked); /* we wouldn't have gotten the * BUFCLEAR event if we * couldn't submit */ - retcode = IssueNextReadRequest(raidPtr, frow, event->col); + retcode = rf_IssueNextReadRequest(raidPtr, frow, event->col); break; case RF_REVENT_BLOCKCLEAR: /* A user-write reconstruction * blockage has been cleared */ DDprintf2("RECON: BLOCKCLEAR EVENT: row %d col %d\n", frow, event->col); - retcode = TryToRead(raidPtr, frow, event->col); + retcode = rf_TryToRead(raidPtr, frow, event->col); break; case RF_REVENT_HEADSEPCLEAR: /* A max-head-separation * reconstruction blockage has been * cleared */ Dprintf2("RECON: HEADSEPCLEAR EVENT: row %d col %d\n", frow, event->col); - retcode = TryToRead(raidPtr, frow, event->col); + retcode = rf_TryToRead(raidPtr, frow, event->col); break; /* a buffer has become ready to write */ case RF_REVENT_BUFREADY: Dprintf2("RECON: BUFREADY EVENT: row %d col %d\n", frow, event->col); - retcode = IssueNextWriteRequest(raidPtr, frow); + retcode = rf_IssueNextWriteRequest(raidPtr, frow); if (rf_floatingRbufDebug) { rf_CheckFloatingRbufCount(raidPtr, 1); } @@ -908,7 +888,7 @@ ProcessReconEvent(raidPtr, frow, event) * recon'd while we were waiting for something else to happen */ case RF_REVENT_SKIP: DDprintf2("RECON: SKIP EVENT: row %d col %d\n", frow, event->col); - retcode = IssueNextReadRequest(raidPtr, frow, event->col); + retcode = rf_IssueNextReadRequest(raidPtr, frow, event->col); break; /* a forced-reconstruction read access has completed. Just @@ -945,8 +925,8 @@ ProcessReconEvent(raidPtr, frow, event) * * returns nonzero if and only if there is nothing left unread on the indicated disk ****************************************************************************************/ -static int -IssueNextReadRequest(raidPtr, row, col) +int +rf_IssueNextReadRequest(raidPtr, row, col) RF_Raid_t *raidPtr; RF_RowCol_t row; RF_RowCol_t col; @@ -975,14 +955,14 @@ IssueNextReadRequest(raidPtr, row, col) /* code left over from when head-sep was based on * parity stripe id */ if (ctrl->curPSID >= raidPtr->reconControl[row]->lastPSID) { - CheckForNewMinHeadSep(raidPtr, row, ++(ctrl->headSepCounter)); + rf_CheckForNewMinHeadSep(raidPtr, row, ++(ctrl->headSepCounter)); return (1); /* finito! */ } /* find the disk offsets of the start of the parity * stripe on both the current disk and the failed * disk. skip this entire parity stripe if either disk * does not appear in the indicated PS */ - status = ComputePSDiskOffsets(raidPtr, ctrl->curPSID, row, col, &ctrl->diskOffset, &rbuf->failedDiskSectorOffset, + status = rf_ComputePSDiskOffsets(raidPtr, ctrl->curPSID, row, col, &ctrl->diskOffset, &rbuf->failedDiskSectorOffset, &rbuf->spRow, &rbuf->spCol, &rbuf->spOffset); if (status) { ctrl->ru_count = RUsPerPU - 1; @@ -1000,7 +980,7 @@ IssueNextReadRequest(raidPtr, row, col) } ctrl->headSepCounter++; if (do_new_check) - CheckForNewMinHeadSep(raidPtr, row, ctrl->headSepCounter); /* update min if needed */ + rf_CheckForNewMinHeadSep(raidPtr, row, ctrl->headSepCounter); /* update min if needed */ /* at this point, we have definitely decided what to do, and we have @@ -1010,7 +990,7 @@ IssueNextReadRequest(raidPtr, row, col) bzero((char *) &raidPtr->recon_tracerecs[col], sizeof(raidPtr->recon_tracerecs[col])); raidPtr->recon_tracerecs[col].reconacc = 1; RF_ETIMER_START(raidPtr->recon_tracerecs[col].recon_timer); - retcode = TryToRead(raidPtr, row, col); + retcode = rf_TryToRead(raidPtr, row, col); return (retcode); } /* tries to issue the next read on the indicated disk. We may be blocked by (a) the heads being too @@ -1018,8 +998,8 @@ IssueNextReadRequest(raidPtr, row, col) * In this case, we issue a head-sep or blockage wait request, which will cause this same routine * to be invoked again later when the blockage has cleared. */ -static int -TryToRead(raidPtr, row, col) +int +rf_TryToRead(raidPtr, row, col) RF_Raid_t *raidPtr; RF_RowCol_t row; RF_RowCol_t col; @@ -1034,7 +1014,7 @@ TryToRead(raidPtr, row, col) /* if the current disk is too far ahead of the others, issue a * head-separation wait and return */ - if (CheckHeadSeparation(raidPtr, ctrl, row, col, ctrl->headSepCounter, which_ru)) + if (rf_CheckHeadSeparation(raidPtr, ctrl, row, col, ctrl->headSepCounter, which_ru)) return (0); RF_LOCK_PSS_MUTEX(raidPtr, row, psid); pssPtr = rf_LookupRUStatus(raidPtr, raidPtr->reconControl[row]->pssTable, psid, which_ru, RF_PSS_CREATE, &created); @@ -1042,7 +1022,7 @@ TryToRead(raidPtr, row, col) /* if recon is blocked on the indicated parity stripe, issue a * block-wait request and return. this also must mark the indicated RU * in the stripe as under reconstruction if not blocked. */ - status = CheckForcedOrBlockedReconstruction(raidPtr, pssPtr, ctrl, row, col, psid, which_ru); + status = rf_CheckForcedOrBlockedReconstruction(raidPtr, pssPtr, ctrl, row, col, psid, which_ru); if (status == RF_PSS_RECON_BLOCKED) { Dprintf2("RECON: Stalling psid %ld ru %d: recon blocked\n", psid, which_ru); goto out; @@ -1077,7 +1057,7 @@ TryToRead(raidPtr, row, col) /* should be ok to use a NULL proc pointer here, all the bufs we use * should be in kernel space */ req = rf_CreateDiskQueueData(RF_IO_TYPE_READ, ctrl->diskOffset, sectorsPerRU, ctrl->rbuf->buffer, psid, which_ru, - ReconReadDoneProc, (void *) ctrl, NULL, &raidPtr->recon_tracerecs[col], (void *) raidPtr, 0, NULL); + rf_ReconReadDoneProc, (void *) ctrl, NULL, &raidPtr->recon_tracerecs[col], (void *) raidPtr, 0, NULL); RF_ASSERT(req); /* XXX -- fix this -- XXX */ @@ -1111,8 +1091,8 @@ out: * ASSUMES THAT THE STRIPE IDENTIFIER IDENTIFIES THE DISKS COMPRISING THE STRIPE * IN THE CORRECT ORDER */ -static int -ComputePSDiskOffsets( +int +rf_ComputePSDiskOffsets( RF_Raid_t * raidPtr, /* raid descriptor */ RF_StripeNum_t psid, /* parity stripe identifier */ RF_RowCol_t row, /* row and column of disk to find the offsets @@ -1224,8 +1204,8 @@ skipit: return (1); } /* this is called when a buffer has become ready to write to the replacement disk */ -static int -IssueNextWriteRequest(raidPtr, row) +INTEGRATE int +rf_IssueNextWriteRequest(raidPtr, row) RF_Raid_t *raidPtr; RF_RowCol_t row; { @@ -1255,7 +1235,7 @@ IssueNextWriteRequest(raidPtr, row) req = rf_CreateDiskQueueData(RF_IO_TYPE_WRITE, rbuf->spOffset, sectorsPerRU, rbuf->buffer, rbuf->parityStripeID, rbuf->which_ru, - ReconWriteDoneProc, (void *) rbuf, NULL, + rf_ReconWriteDoneProc, (void *) rbuf, NULL, &raidPtr->recon_tracerecs[fcol], (void *) raidPtr, 0, NULL); @@ -1272,8 +1252,8 @@ IssueNextWriteRequest(raidPtr, row) * * called at interrupt context in the kernel, so don't do anything illegal here. */ -static int -ReconReadDoneProc(arg, status) +int +rf_ReconReadDoneProc(arg, status) void *arg; int status; { @@ -1301,8 +1281,8 @@ ReconReadDoneProc(arg, status) * * called at interrupt context in the kernel, so don't do anything illegal here. */ -static int -ReconWriteDoneProc(arg, status) +int +rf_ReconWriteDoneProc(arg, status) void *arg; int status; { @@ -1320,8 +1300,8 @@ ReconWriteDoneProc(arg, status) /* computes a new minimum head sep, and wakes up anyone who needs to be woken as a result */ -static void -CheckForNewMinHeadSep(raidPtr, row, hsCtr) +void +rf_CheckForNewMinHeadSep(raidPtr, row, hsCtr) RF_Raid_t *raidPtr; RF_RowCol_t row; RF_HeadSepLimit_t hsCtr; @@ -1370,8 +1350,8 @@ CheckForNewMinHeadSep(raidPtr, row, hsCtr) * returns non-zero if and only if we have to stop working on the indicated disk * due to a head-separation delay. */ -static int -CheckHeadSeparation( +int +rf_CheckHeadSeparation( RF_Raid_t * raidPtr, RF_PerDiskReconCtrl_t * ctrl, RF_RowCol_t row, @@ -1435,8 +1415,8 @@ CheckHeadSeparation( * * ASSUMES THE PSS MUTEX IS LOCKED UPON ENTRY */ -static int -CheckForcedOrBlockedReconstruction( +INTEGRATE int +rf_CheckForcedOrBlockedReconstruction( RF_Raid_t * raidPtr, RF_ReconParityStripeStatus_t * pssPtr, RF_PerDiskReconCtrl_t * ctrl, @@ -1544,7 +1524,7 @@ rf_ForceOrBlockRecon(raidPtr, asmap, cbFunc, cbArg) printf("[%d] promoted read from row %d col %d\n", tid, row, diskno); } else { new_rbuf = rf_MakeReconBuffer(raidPtr, row, diskno, RF_RBUF_TYPE_FORCED); /* create new buf */ - ComputePSDiskOffsets(raidPtr, psid, row, diskno, &offset, &fd_offset, + rf_ComputePSDiskOffsets(raidPtr, psid, row, diskno, &offset, &fd_offset, &new_rbuf->spRow, &new_rbuf->spCol, &new_rbuf->spOffset); /* find offsets & spare * location */ new_rbuf->parityStripeID = psid; /* fill in the buffer */ @@ -1555,7 +1535,7 @@ rf_ForceOrBlockRecon(raidPtr, asmap, cbFunc, cbArg) /* use NULL b_proc b/c all addrs * should be in kernel space */ req = rf_CreateDiskQueueData(RF_IO_TYPE_READ, offset + which_ru * sectorsPerRU, sectorsPerRU, new_rbuf->buffer, - psid, which_ru, (int (*) (void *, int)) ForceReconReadDoneProc, (void *) new_rbuf, NULL, + psid, which_ru, (int (*) (void *, int)) rf_ForceReconReadDoneProc, (void *) new_rbuf, NULL, NULL, (void *) raidPtr, 0, NULL); RF_ASSERT(req); /* XXX -- fix this -- @@ -1589,8 +1569,8 @@ rf_ForceOrBlockRecon(raidPtr, asmap, cbFunc, cbArg) * all we do is schedule the FORCEDREADONE event. * called at interrupt context in the kernel, so don't do anything illegal here. */ -static void -ForceReconReadDoneProc(arg, status) +void +rf_ForceReconReadDoneProc(arg, status) void *arg; int status; { diff --git a/sys/dev/raidframe/rf_revent.c b/sys/dev/raidframe/rf_revent.c index 6b54f94bf6c..e1ad4661ac1 100644 --- a/sys/dev/raidframe/rf_revent.c +++ b/sys/dev/raidframe/rf_revent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rf_revent.c,v 1.5 1999/08/02 15:42:48 peter Exp $ */ +/* $OpenBSD: rf_revent.c,v 1.6 1999/08/03 13:56:38 peter Exp $ */ /* $NetBSD: rf_revent.c,v 1.4 1999/03/14 21:53:31 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. @@ -40,8 +40,6 @@ #include "rf_desc.h" #include "rf_shutdown.h" -#include <sys/kernel.h> - static RF_FreeList_t *rf_revent_freelist; #define RF_MAX_FREE_REVENT 128 #define RF_REVENT_INC 8 @@ -109,8 +107,6 @@ rf_GetNextReconEvent(reconDesc, row, continueFunc, continueArg) void (*continueFunc) (void *); void *continueArg; { - int s; - RF_Raid_t *raidPtr = reconDesc->raidPtr; RF_ReconCtrl_t *rctrl = raidPtr->reconControl[row]; RF_ReconEvent_t *event; @@ -121,46 +117,47 @@ rf_GetNextReconEvent(reconDesc, row, continueFunc, continueArg) * must be equivalent * conditions */ - rctrl->continueFunc = continueFunc; rctrl->continueArg = continueArg; -/* start with a simple premise. Allow 100 ms for recon, and then - * sleep for the 2 ms to allow use of the CPU. This resulted in a CPU - * utilisation of about 25% locally, and a very responsive system - PMG - */ -#define RECON_TIME ((100 * hz) / 1000) - if (reconDesc->reconExecTimerRunning) { - int status; - RF_int64 ticks; +#define MAX_RECON_EXEC_USECS (100 * 1000) /* 100 ms */ +#define RECON_DELAY_MS 25 +#define RECON_TIMO ((RECON_DELAY_MS * hz) / 1000) - s = splclock(); - ticks = (mono_time.tv_sec * 1000000 + mono_time.tv_usec) - - reconDesc->reconExecTimerRunning; - splx(s); - - if (ticks >= (1000000 / RECON_TIME)) { - /* we've been running too long. delay for RECON_TIME */ + /* 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_USECS + * delay for RECON_DELAY_MS 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->reconExecuSecs += RF_ETIMER_VAL_US(reconDesc->recon_exec_timer); + if (reconDesc->reconExecuSecs > reconDesc->maxReconExecuSecs) + reconDesc->maxReconExecuSecs = reconDesc->reconExecuSecs; + if (reconDesc->reconExecuSecs >= MAX_RECON_EXEC_USECS) { + /* we've been running too long - sleep */ #if RF_RECON_STATS > 0 reconDesc->numReconExecDelays++; #endif /* RF_RECON_STATS > 0 */ - status = tsleep(&reconDesc->reconExecTicks, PRIBIO, "recon delay", RECON_TIME / 5); + status = tsleep(&reconDesc->reconExecuSecs, PRIBIO, "recon delay", RECON_TIMO); RF_ASSERT(status == EWOULDBLOCK); + reconDesc->reconExecuSecs = 0; } } - while (!rctrl->eventQueue) { #if RF_RECON_STATS > 0 reconDesc->numReconEventWaits++; #endif /* RF_RECON_STATS > 0 */ DO_WAIT(rctrl); + reconDesc->reconExecuSecs = 0; /* we've just waited */ } - s = splclock(); - /* set time to now */ - reconDesc->reconExecTimerRunning = mono_time.tv_sec * 1000000 + - mono_time.tv_usec; - splx(s); + + RF_ETIMER_START(reconDesc->recon_exec_timer); + reconDesc->reconExecTimerRunning = 1; event = rctrl->eventQueue; rctrl->eventQueue = event->next; diff --git a/sys/dev/raidframe/rf_sys.c b/sys/dev/raidframe/rf_sys.c index 671fa46dcc9..68d8465035e 100644 --- a/sys/dev/raidframe/rf_sys.c +++ b/sys/dev/raidframe/rf_sys.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rf_sys.c,v 1.2 1999/02/16 00:03:29 niklas Exp $ */ +/* $OpenBSD: rf_sys.c,v 1.3 1999/08/03 13:56:38 peter Exp $ */ /* $NetBSD: rf_sys.c,v 1.3 1999/02/05 00:06:18 oster Exp $ */ /* * rf_sys.c @@ -42,21 +42,10 @@ extern struct rpb *rpb; -/* timer stuff */ -long rf_timer_max_val; -long rf_timer_ticks_per_second; -unsigned long rf_timer_ticks_per_usec; - int rf_ConfigureEtimer(listp) RF_ShutdownList_t **listp; { - /* XXX just picking some random values to keep things happy... without - * these set, stuff will panic on division by zero errors!! */ - rf_timer_ticks_per_second = 233100233; - rf_timer_max_val = RF_DEF_TIMER_MAX_VAL; - rf_timer_ticks_per_usec = rf_timer_ticks_per_second / 1000000; - return (0); } diff --git a/sys/dev/raidframe/rf_utils.h b/sys/dev/raidframe/rf_utils.h index fb53ecd9719..1e5a9d3e872 100644 --- a/sys/dev/raidframe/rf_utils.h +++ b/sys/dev/raidframe/rf_utils.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rf_utils.h,v 1.2 1999/02/16 00:03:33 niklas Exp $ */ +/* $OpenBSD: rf_utils.h,v 1.3 1999/08/03 13:56:38 peter Exp $ */ /* $NetBSD: rf_utils.h,v 1.3 1999/02/05 00:06:18 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. @@ -52,6 +52,7 @@ int rf_atoi(char *p); int rf_htoi(char *p); #define RF_USEC_PER_SEC 1000000 +#define RF_TIMEVAL_TO_US(_t_) (((_t_).tv_sec) * RF_USEC_PER_SEC + (_t_).tv_usec) #define RF_TIMEVAL_DIFF(_start_,_end_,_diff_) { \ if ((_end_)->tv_usec < (_start_)->tv_usec) { \ (_diff_)->tv_usec = ((_end_)->tv_usec + RF_USEC_PER_SEC) \ |