From 664e80aabbf998c4dced640f7a07dea3eb05d7fb Mon Sep 17 00:00:00 2001 From: Peter Galbavy Date: Tue, 11 Jan 2000 18:02:24 +0000 Subject: sync with NetBSD - removed threadid stuff - removed unused files - general tidyup - you can no longer configure the same unit twice (without de-configuring first of course). Again, this has only been tested locally on IDE disks. Further testing and feedback would be appreciated. --- sys/dev/raidframe/rf_reconstruct.c | 221 ++++++++++++++++++------------------- 1 file changed, 109 insertions(+), 112 deletions(-) (limited to 'sys/dev/raidframe/rf_reconstruct.c') diff --git a/sys/dev/raidframe/rf_reconstruct.c b/sys/dev/raidframe/rf_reconstruct.c index 08cfe417d0b..e731bcc42a3 100644 --- a/sys/dev/raidframe/rf_reconstruct.c +++ b/sys/dev/raidframe/rf_reconstruct.c @@ -1,5 +1,5 @@ -/* $OpenBSD: rf_reconstruct.c,v 1.7 2000/01/11 14:51:37 peter Exp $ */ -/* $NetBSD: rf_reconstruct.c,v 1.9 2000/01/05 02:57:29 oster Exp $ */ +/* $OpenBSD: rf_reconstruct.c,v 1.8 2000/01/11 18:02:23 peter Exp $ */ +/* $NetBSD: rf_reconstruct.c,v 1.14 2000/01/09 03:14:33 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -52,7 +52,6 @@ #include "rf_reconutil.h" #include "rf_revent.h" #include "rf_reconbuffer.h" -#include "rf_threadid.h" #include "rf_acctrace.h" #include "rf_etimer.h" #include "rf_dag.h" @@ -62,7 +61,6 @@ #include "rf_debugprint.h" #include "rf_driver.h" #include "rf_utils.h" -#include "rf_cpuutil.h" #include "rf_shutdown.h" #include "rf_kintf.h" @@ -77,21 +75,9 @@ #define Dprintf5(s,a,b,c,d,e) if (rf_reconDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),(void *)((unsigned long)d),(void *)((unsigned long)e),NULL,NULL,NULL) #define Dprintf6(s,a,b,c,d,e,f) if (rf_reconDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),(void *)((unsigned long)d),(void *)((unsigned long)e),(void *)((unsigned long)f),NULL,NULL) #define Dprintf7(s,a,b,c,d,e,f,g) if (rf_reconDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),(void *)((unsigned long)d),(void *)((unsigned long)e),(void *)((unsigned long)f),(void *)((unsigned long)g),NULL) -#define Dprintf8(s,a,b,c,d,e,f,g,h) if (rf_reconDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),(void *)((unsigned long)d),(void *)((unsigned long)e),(void *)((unsigned long)f),(void *)((unsigned long)g),(void *)((unsigned long)h)) #define DDprintf1(s,a) if (rf_reconDebug) rf_debug_printf(s,(void *)((unsigned long)a),NULL,NULL,NULL,NULL,NULL,NULL,NULL) #define DDprintf2(s,a,b) if (rf_reconDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),NULL,NULL,NULL,NULL,NULL,NULL) -#define DDprintf3(s,a,b,c) if (rf_reconDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),NULL,NULL,NULL,NULL,NULL) -#define DDprintf4(s,a,b,c,d) if (rf_reconDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),(void *)((unsigned long)d),NULL,NULL,NULL,NULL) -#define DDprintf5(s,a,b,c,d,e) if (rf_reconDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),(void *)((unsigned long)d),(void *)((unsigned long)e),NULL,NULL,NULL) -#define DDprintf6(s,a,b,c,d,e,f) if (rf_reconDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),(void *)((unsigned long)d),(void *)((unsigned long)e),(void *)((unsigned long)f),NULL,NULL) -#define DDprintf7(s,a,b,c,d,e,f,g) if (rf_reconDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),(void *)((unsigned long)d),(void *)((unsigned long)e),(void *)((unsigned long)f),(void *)((unsigned long)g),NULL) -#define DDprintf8(s,a,b,c,d,e,f,g,h) if (rf_reconDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),(void *)((unsigned long)d),(void *)((unsigned long)e),(void *)((unsigned long)f),(void *)((unsigned long)g),(void *)((unsigned long)h)) - -#if 0 -static RF_Thread_t recon_thr_handle; -static int recon_thread_initialized = 0; -#endif static RF_FreeList_t *rf_recond_freelist; #define RF_MAX_FREE_RECOND 4 @@ -118,11 +104,6 @@ int rf_IssueNextWriteRequest __P((RF_Raid_t *, RF_RowCol_t)); 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)); void rf_SignalReconDone __P((RF_Raid_t *)); -/* XXX these should be in a .h file somewhere */ -int raidlookup __P((char *, struct proc *, struct vnode **)); -int raidwrite_component_label(dev_t, struct vnode *, RF_ComponentLabel_t *); -int raidread_component_label(dev_t, struct vnode *, RF_ComponentLabel_t *); - struct RF_ReconDoneProc_s { void (*proc) (RF_Raid_t *, void *); void *arg; @@ -167,7 +148,7 @@ rf_RegisterReconDoneProc( *handlep = p; return (0); } -/***************************************************************************************** +/************************************************************************** * * sets up the parameters that will be used by the reconstruction process * currently there are none, except for those that the layout-specific @@ -175,7 +156,7 @@ rf_RegisterReconDoneProc( * * in the kernel, we fire off the recon thread. * - ****************************************************************************************/ + **************************************************************************/ void rf_ShutdownReconstruction(ignored) void *ignored; @@ -207,12 +188,6 @@ rf_ConfigureReconstruction(listp) rf_ShutdownReconstruction(NULL); return (rc); } -#if 0 - if (!recon_thread_initialized) { - RF_CREATE_THREAD(recon_thr_handle, rf_ReconKernelThread, NULL, "raid_recon"); - recon_thread_initialized = 1; - } -#endif return (0); } @@ -675,7 +650,7 @@ rf_ContinueReconstructFailedDisk(reconDesc) /* now start up the actual reconstruction: issue a read for * each surviving disk */ - rf_start_cpu_monitor(); + reconDesc->numDisksDone = 0; for (i = 0; i < raidPtr->numCol; i++) { if (i != col) { @@ -740,8 +715,6 @@ rf_ContinueReconstructFailedDisk(reconDesc) reconDesc->state = 5; case 5: - rf_stop_cpu_monitor(); - /* Success: mark the dead disk as reconstructed. We quiesce * the array here to assure no nasty interactions with pending * user accesses when we free up the psstatus structure as @@ -784,7 +757,7 @@ rf_ContinueReconstructFailedDisk(reconDesc) (int) raidPtr->reconControl[row]->starttime.tv_sec, (int) raidPtr->reconControl[row]->starttime.tv_usec, (int) etime.tv_sec, (int) etime.tv_usec); - rf_print_cpu_util("reconstruction"); + #if RF_RECON_STATS > 0 printf("Total head-sep stall count was %d\n", (int) reconDesc->hsStallCount); @@ -798,10 +771,11 @@ rf_ContinueReconstructFailedDisk(reconDesc) 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 - ****************************************************************************************/ + * returns nonzero if and only if there is nothing left unread on the + * indicated disk + *****************************************************************************/ int rf_ProcessReconEvent(raidPtr, frow, event) RF_Raid_t *raidPtr; @@ -912,23 +886,27 @@ rf_ProcessReconEvent(raidPtr, frow, event) return (retcode); } -/***************************************************************************************** +/***************************************************************************** + * + * find the next thing that's needed on the indicated disk, and issue + * a read request for it. We assume that the reconstruction buffer + * associated with this process is free to receive the data. If + * reconstruction is blocked on the indicated RU, we issue a + * blockage-release request instead of a physical disk read request. + * If the current disk gets too far ahead of the others, we issue a + * head-separation wait request and return. * - * find the next thing that's needed on the indicated disk, and issue a read - * request for it. We assume that the reconstruction buffer associated with this - * process is free to receive the data. If reconstruction is blocked on the - * indicated RU, we issue a blockage-release request instead of a physical disk - * read request. If the current disk gets too far ahead of the others, we issue - * a head-separation wait request and return. + * ctrl->{ru_count, curPSID, diskOffset} and + * rbuf->failedDiskSectorOffset are maintained to point the the unit + * we're currently accessing. Note that this deviates from the + * standard C idiom of having counters point to the next thing to be + * accessed. This allows us to easily retry when we're blocked by + * head separation or reconstruction-blockage events. * - * ctrl->{ru_count, curPSID, diskOffset} and rbuf->failedDiskSectorOffset are - * maintained to point the the unit we're currently accessing. Note that this deviates - * from the standard C idiom of having counters point to the next thing to be - * accessed. This allows us to easily retry when we're blocked by head separation - * or reconstruction-blockage events. + * returns nonzero if and only if there is nothing left unread on the + * indicated disk * - * returns nonzero if and only if there is nothing left unread on the indicated disk - ****************************************************************************************/ + *****************************************************************************/ int rf_IssueNextReadRequest(raidPtr, row, col) RF_Raid_t *raidPtr; @@ -997,11 +975,16 @@ rf_IssueNextReadRequest(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 - * far apart, or (b) recon on the indicated RU being blocked due to a write by a user thread. - * 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. + +/* + * tries to issue the next read on the indicated disk. We may be + * blocked by (a) the heads being too far apart, or (b) recon on the + * indicated RU being blocked due to a write by a user thread. 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. */ + int rf_TryToRead(raidPtr, row, col) RF_Raid_t *raidPtr; @@ -1075,26 +1058,30 @@ out: } -/* given a parity stripe ID, we want to find out whether both the current disk and the - * failed disk exist in that parity stripe. If not, we want to skip this whole PS. - * If so, we want to find the disk offset of the start of the PS on both the current - * disk and the failed disk. +/* + * given a parity stripe ID, we want to find out whether both the + * current disk and the failed disk exist in that parity stripe. If + * not, we want to skip this whole PS. If so, we want to find the + * disk offset of the start of the PS on both the current disk and the + * failed disk. * - * this works by getting a list of disks comprising the indicated parity stripe, and - * searching the list for the current and failed disks. Once we've decided they both - * exist in the parity stripe, we need to decide whether each is data or parity, - * so that we'll know which mapping function to call to get the corresponding disk + * this works by getting a list of disks comprising the indicated + * parity stripe, and searching the list for the current and failed + * disks. Once we've decided they both exist in the parity stripe, we + * need to decide whether each is data or parity, so that we'll know + * which mapping function to call to get the corresponding disk * offsets. * - * this is kind of unpleasant, but doing it this way allows the reconstruction code - * to use parity stripe IDs rather than physical disks address to march through the - * failed disk, which greatly simplifies a lot of code, as well as eliminating the - * need for a reverse-mapping function. I also think it will execute faster, since - * the calls to the mapping module are kept to a minimum. + * this is kind of unpleasant, but doing it this way allows the + * reconstruction code to use parity stripe IDs rather than physical + * disks address to march through the failed disk, which greatly + * simplifies a lot of code, as well as eliminating the need for a + * reverse-mapping function. I also think it will execute faster, + * since the calls to the mapping module are kept to a minimum. * - * ASSUMES THAT THE STRIPE IDENTIFIER IDENTIFIES THE DISKS COMPRISING THE STRIPE - * IN THE CORRECT ORDER - */ + * ASSUMES THAT THE STRIPE IDENTIFIER IDENTIFIES THE DISKS COMPRISING + * THE STRIPE IN THE CORRECT ORDER */ + int rf_ComputePSDiskOffsets( RF_Raid_t * raidPtr, /* raid descriptor */ @@ -1250,11 +1237,14 @@ rf_IssueNextWriteRequest(raidPtr, row) return (0); } -/* this gets called upon the completion of a reconstruction read operation - * the arg is a pointer to the per-disk reconstruction control structure - * for the process that just finished a read. + +/* + * this gets called upon the completion of a reconstruction read + * operation the arg is a pointer to the per-disk reconstruction + * control structure for the process that just finished a read. * - * called at interrupt context in the kernel, so don't do anything illegal here. + * called at interrupt context in the kernel, so don't do anything + * illegal here. */ int rf_ReconReadDoneProc(arg, status) @@ -1303,7 +1293,10 @@ rf_ReconWriteDoneProc(arg, status) } -/* computes a new minimum head sep, and wakes up anyone who needs to be woken as a result */ +/* + * computes a new minimum head sep, and wakes up anyone who needs to + * be woken as a result + */ void rf_CheckForNewMinHeadSep(raidPtr, row, hsCtr) RF_Raid_t *raidPtr; @@ -1343,16 +1336,18 @@ rf_CheckForNewMinHeadSep(raidPtr, row, hsCtr) } RF_UNLOCK_MUTEX(reconCtrlPtr->rb_mutex); } -/* checks to see that the maximum head separation will not be violated - * if we initiate a reconstruction I/O on the indicated disk. Limiting the - * maximum head separation between two disks eliminates the nasty buffer-stall - * conditions that occur when one disk races ahead of the others and consumes - * all of the floating recon buffers. This code is complex and unpleasant - * but it's necessary to avoid some very nasty, albeit fairly rare, - * reconstruction behavior. + +/* + * checks to see that the maximum head separation will not be violated + * if we initiate a reconstruction I/O on the indicated disk. + * Limiting the maximum head separation between two disks eliminates + * the nasty buffer-stall conditions that occur when one disk races + * ahead of the others and consumes all of the floating recon buffers. + * This code is complex and unpleasant but it's necessary to avoid + * some very nasty, albeit fairly rare, reconstruction behavior. * - * returns non-zero if and only if we have to stop working on the indicated disk - * due to a head-separation delay. + * returns non-zero if and only if we have to stop working on the + * indicated disk due to a head-separation delay. */ int rf_CheckHeadSeparation( @@ -1365,7 +1360,7 @@ rf_CheckHeadSeparation( { RF_ReconCtrl_t *reconCtrlPtr = raidPtr->reconControl[row]; RF_CallbackDesc_t *cb, *p, *pt; - int retval = 0, tid; + int retval = 0; /* if we're too far ahead of the slowest disk, stop working on this * disk until the slower ones catch up. We do this by scheduling a @@ -1375,12 +1370,13 @@ rf_CheckHeadSeparation( * separation before we'll wake up. * */ - rf_get_threadid(tid); RF_LOCK_MUTEX(reconCtrlPtr->rb_mutex); if ((raidPtr->headSepLimit >= 0) && ((ctrl->headSepCounter - reconCtrlPtr->minHeadSepCounter) > raidPtr->headSepLimit)) { - Dprintf6("[%d] RECON: head sep stall: row %d col %d hsCtr %ld minHSCtr %ld limit %ld\n", - tid, row, col, ctrl->headSepCounter, reconCtrlPtr->minHeadSepCounter, raidPtr->headSepLimit); + Dprintf6("raid%d: RECON: head sep stall: row %d col %d hsCtr %ld minHSCtr %ld limit %ld\n", + raidPtr->raidid, row, col, ctrl->headSepCounter, + reconCtrlPtr->minHeadSepCounter, + raidPtr->headSepLimit); cb = rf_AllocCallbackDesc(); /* the minHeadSepCounter value we have to get to before we'll * wake up. build in 20% hysteresis. */ @@ -1412,10 +1408,10 @@ rf_CheckHeadSeparation( return (retval); } -/* checks to see if reconstruction has been either forced or blocked by a user operation. - * if forced, we skip this RU entirely. - * else if blocked, put ourselves on the wait list. - * else return 0. +/* + * checks to see if reconstruction has been either forced or blocked + * by a user operation. if forced, we skip this RU entirely. else if + * blocked, put ourselves on the wait list. else return 0. * * ASSUMES THE PSS MUTEX IS LOCKED UPON ENTRY */ @@ -1452,11 +1448,13 @@ rf_CheckForcedOrBlockedReconstruction( return (retcode); } -/* if reconstruction is currently ongoing for the indicated stripeID, reconstruction - * is forced to completion and we return non-zero to indicate that the caller must - * wait. If not, then reconstruction is blocked on the indicated stripe and the - * routine returns zero. If and only if we return non-zero, we'll cause the cbFunc - * to get invoked with the cbArg when the reconstruction has completed. +/* + * if reconstruction is currently ongoing for the indicated stripeID, + * reconstruction is forced to completion and we return non-zero to + * indicate that the caller must wait. If not, then reconstruction is + * blocked on the indicated stripe and the routine returns zero. If + * and only if we return non-zero, we'll cause the cbFunc to get + * invoked with the cbArg when the reconstruction has completed. */ int rf_ForceOrBlockRecon(raidPtr, asmap, cbFunc, cbArg) @@ -1477,7 +1475,6 @@ rf_ForceOrBlockRecon(raidPtr, asmap, cbFunc, cbArg) * offset */ RF_RowCol_t *diskids; RF_RowCol_t stripe; - int tid; RF_ReconUnitNum_t which_ru; /* RU within parity stripe */ RF_RowCol_t fcol, diskno, i; RF_ReconBuffer_t *new_rbuf; /* ptr to newly allocated rbufs */ @@ -1485,7 +1482,6 @@ rf_ForceOrBlockRecon(raidPtr, asmap, cbFunc, cbArg) RF_CallbackDesc_t *cb; int created = 0, nPromoted; - rf_get_threadid(tid); psid = rf_MapStripeIDToParityStripeID(&raidPtr->Layout, stripeID, &which_ru); RF_LOCK_PSS_MUTEX(raidPtr, row, psid); @@ -1525,7 +1521,7 @@ rf_ForceOrBlockRecon(raidPtr, asmap, cbFunc, cbArg) if (pssPtr->issued[diskno]) { nPromoted = rf_DiskIOPromote(&raidPtr->Queues[row][diskno], psid, which_ru); if (rf_reconDebug && nPromoted) - printf("[%d] promoted read from row %d col %d\n", tid, row, diskno); + printf("raid%d: promoted read from row %d col %d\n", raidPtr->raidid, row, diskno); } else { new_rbuf = rf_MakeReconBuffer(raidPtr, row, diskno, RF_RBUF_TYPE_FORCED); /* create new buf */ rf_ComputePSDiskOffsets(raidPtr, psid, row, diskno, &offset, &fd_offset, @@ -1547,13 +1543,14 @@ rf_ForceOrBlockRecon(raidPtr, asmap, cbFunc, cbArg) new_rbuf->arg = req; rf_DiskIOEnqueue(&raidPtr->Queues[row][diskno], req, RF_IO_NORMAL_PRIORITY); /* enqueue the I/O */ - Dprintf3("[%d] Issued new read req on row %d col %d\n", tid, row, diskno); + Dprintf3("raid%d: Issued new read req on row %d col %d\n", raidPtr->raidid, row, diskno); } } /* if the write is sitting in the disk queue, elevate its * priority */ if (rf_DiskIOPromote(&raidPtr->Queues[row][fcol], psid, which_ru)) - printf("[%d] promoted write to row %d col %d\n", tid, row, fcol); + printf("raid%d: promoted write to row %d col %d\n", + raidPtr->raidid, row, fcol); } /* install a callback descriptor to be invoked when recon completes on * this parity stripe. */ @@ -1564,7 +1561,8 @@ rf_ForceOrBlockRecon(raidPtr, asmap, cbFunc, cbArg) cb->callbackArg.p = (void *) cbArg; cb->next = pssPtr->procWaitList; pssPtr->procWaitList = cb; - DDprintf2("[%d] Waiting for forced recon on psid %ld\n", tid, psid); + DDprintf2("raid%d: Waiting for forced recon on psid %ld\n", + raidPtr->raidid, psid); RF_UNLOCK_PSS_MUTEX(raidPtr, row, psid); return (1); @@ -1599,10 +1597,9 @@ rf_UnblockRecon(raidPtr, asmap) RF_ReconParityStripeStatus_t *pssPtr; RF_ReconUnitNum_t which_ru; RF_StripeNum_t psid; - int tid, created = 0; + int created = 0; RF_CallbackDesc_t *cb; - rf_get_threadid(tid); psid = rf_MapStripeIDToParityStripeID(&raidPtr->Layout, stripeID, &which_ru); RF_LOCK_PSS_MUTEX(raidPtr, row, psid); pssPtr = rf_LookupRUStatus(raidPtr, raidPtr->reconControl[row]->pssTable, psid, which_ru, RF_PSS_NONE, &created); @@ -1619,7 +1616,8 @@ rf_UnblockRecon(raidPtr, asmap) goto out; } pssPtr->blockCount--; - Dprintf3("[%d] unblocking recon on psid %ld: blockcount is %d\n", tid, psid, pssPtr->blockCount); + Dprintf3("raid%d: unblocking recon on psid %ld: blockcount is %d\n", + raidPtr->raidid, psid, pssPtr->blockCount); if (pssPtr->blockCount == 0) { /* if recon blockage has been released */ /* unblock recon before calling CauseReconEvent in case @@ -1628,18 +1626,17 @@ rf_UnblockRecon(raidPtr, asmap) pssPtr->flags &= ~RF_PSS_RECON_BLOCKED; - while (pssPtr->blockWaitList) { /* spin through the block-wait - * list and release all the - * waiters */ + while (pssPtr->blockWaitList) { + /* spin through the block-wait list and + release all the waiters */ cb = pssPtr->blockWaitList; pssPtr->blockWaitList = cb->next; cb->next = NULL; rf_CauseReconEvent(raidPtr, cb->row, cb->col, NULL, RF_REVENT_BLOCKCLEAR); rf_FreeCallbackDesc(cb); } - if (!(pssPtr->flags & RF_PSS_UNDER_RECON)) { /* if no recon was - * requested while recon - * was blocked */ + if (!(pssPtr->flags & RF_PSS_UNDER_RECON)) { + /* if no recon was requested while recon was blocked */ rf_PSStatusDelete(raidPtr, raidPtr->reconControl[row]->pssTable, pssPtr); } } -- cgit v1.2.3