Home | History | Annotate | Line # | Download | only in raidframe
rf_driver.c revision 1.141
      1  1.141     oster /*	$NetBSD: rf_driver.c,v 1.141 2023/09/17 20:07:39 oster Exp $	*/
      2    1.9     oster /*-
      3    1.9     oster  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      4    1.9     oster  * All rights reserved.
      5    1.9     oster  *
      6    1.9     oster  * This code is derived from software contributed to The NetBSD Foundation
      7    1.9     oster  * by Greg Oster
      8    1.9     oster  *
      9    1.9     oster  * Redistribution and use in source and binary forms, with or without
     10    1.9     oster  * modification, are permitted provided that the following conditions
     11    1.9     oster  * are met:
     12    1.9     oster  * 1. Redistributions of source code must retain the above copyright
     13    1.9     oster  *    notice, this list of conditions and the following disclaimer.
     14    1.9     oster  * 2. Redistributions in binary form must reproduce the above copyright
     15    1.9     oster  *    notice, this list of conditions and the following disclaimer in the
     16    1.9     oster  *    documentation and/or other materials provided with the distribution.
     17    1.9     oster  *
     18    1.9     oster  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     19    1.9     oster  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     20    1.9     oster  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     21    1.9     oster  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     22    1.9     oster  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     23    1.9     oster  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     24    1.9     oster  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     25    1.9     oster  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     26    1.9     oster  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     27    1.9     oster  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     28    1.9     oster  * POSSIBILITY OF SUCH DAMAGE.
     29    1.9     oster  */
     30    1.9     oster 
     31    1.1     oster /*
     32    1.1     oster  * Copyright (c) 1995 Carnegie-Mellon University.
     33    1.1     oster  * All rights reserved.
     34    1.1     oster  *
     35    1.1     oster  * Author: Mark Holland, Khalil Amiri, Claudson Bornstein, William V. Courtright II,
     36    1.1     oster  *         Robby Findler, Daniel Stodolsky, Rachad Youssef, Jim Zelenka
     37    1.1     oster  *
     38    1.1     oster  * Permission to use, copy, modify and distribute this software and
     39    1.1     oster  * its documentation is hereby granted, provided that both the copyright
     40    1.1     oster  * notice and this permission notice appear in all copies of the
     41    1.1     oster  * software, derivative works or modified versions, and any portions
     42    1.1     oster  * thereof, and that both notices appear in supporting documentation.
     43    1.1     oster  *
     44    1.1     oster  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     45    1.1     oster  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     46    1.1     oster  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     47    1.1     oster  *
     48    1.1     oster  * Carnegie Mellon requests users of this software to return to
     49    1.1     oster  *
     50    1.1     oster  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     51    1.1     oster  *  School of Computer Science
     52    1.1     oster  *  Carnegie Mellon University
     53    1.1     oster  *  Pittsburgh PA 15213-3890
     54    1.1     oster  *
     55    1.1     oster  * any improvements or extensions that they make and grant Carnegie the
     56    1.1     oster  * rights to redistribute these changes.
     57    1.1     oster  */
     58    1.1     oster 
     59    1.1     oster /******************************************************************************
     60    1.1     oster  *
     61    1.1     oster  * rf_driver.c -- main setup, teardown, and access routines for the RAID driver
     62    1.1     oster  *
     63    1.1     oster  * all routines are prefixed with rf_ (raidframe), to avoid conficts.
     64    1.1     oster  *
     65    1.1     oster  ******************************************************************************/
     66    1.1     oster 
     67   1.44     lukem 
     68   1.44     lukem #include <sys/cdefs.h>
     69  1.141     oster __KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.141 2023/09/17 20:07:39 oster Exp $");
     70   1.71    martin 
     71  1.119        ad #ifdef _KERNEL_OPT
     72   1.71    martin #include "opt_raid_diagnostic.h"
     73  1.119        ad #endif
     74    1.1     oster 
     75    1.1     oster #include <sys/param.h>
     76    1.1     oster #include <sys/systm.h>
     77    1.1     oster #include <sys/ioctl.h>
     78    1.1     oster #include <sys/fcntl.h>
     79    1.1     oster #include <sys/vnode.h>
     80    1.1     oster 
     81    1.1     oster 
     82    1.1     oster #include "rf_archs.h"
     83    1.1     oster #include "rf_threadstuff.h"
     84    1.1     oster 
     85    1.1     oster #include <sys/errno.h>
     86    1.1     oster 
     87    1.1     oster #include "rf_raid.h"
     88    1.1     oster #include "rf_dag.h"
     89    1.1     oster #include "rf_aselect.h"
     90    1.1     oster #include "rf_diskqueue.h"
     91    1.1     oster #include "rf_parityscan.h"
     92    1.1     oster #include "rf_alloclist.h"
     93    1.1     oster #include "rf_dagutils.h"
     94    1.1     oster #include "rf_utils.h"
     95    1.1     oster #include "rf_etimer.h"
     96    1.1     oster #include "rf_acctrace.h"
     97    1.1     oster #include "rf_general.h"
     98    1.1     oster #include "rf_desc.h"
     99    1.1     oster #include "rf_states.h"
    100    1.1     oster #include "rf_decluster.h"
    101    1.1     oster #include "rf_map.h"
    102    1.1     oster #include "rf_revent.h"
    103    1.1     oster #include "rf_callback.h"
    104    1.1     oster #include "rf_engine.h"
    105    1.1     oster #include "rf_mcpair.h"
    106    1.1     oster #include "rf_nwayxor.h"
    107    1.1     oster #include "rf_copyback.h"
    108    1.1     oster #include "rf_driver.h"
    109    1.1     oster #include "rf_options.h"
    110    1.1     oster #include "rf_shutdown.h"
    111   1.24     oster #include "rf_kintf.h"
    112  1.122       jld #include "rf_paritymap.h"
    113    1.1     oster 
    114    1.1     oster #include <sys/buf.h>
    115    1.1     oster 
    116   1.61     oster #ifndef RF_ACCESS_DEBUG
    117   1.61     oster #define RF_ACCESS_DEBUG 0
    118   1.61     oster #endif
    119   1.61     oster 
    120    1.1     oster /* rad == RF_RaidAccessDesc_t */
    121    1.1     oster #define RF_MAX_FREE_RAD 128
    122   1.88     oster #define RF_MIN_FREE_RAD  32
    123    1.1     oster 
    124    1.1     oster /* main configuration routines */
    125    1.1     oster static int raidframe_booted = 0;
    126    1.1     oster 
    127    1.6     oster static void rf_ConfigureDebug(RF_Config_t * cfgPtr);
    128    1.1     oster static void set_debug_option(char *name, long val);
    129    1.1     oster static void rf_UnconfigureArray(void);
    130    1.1     oster static void rf_ShutdownRDFreeList(void *);
    131  1.138     oster static int rf_ConfigureRDFreeList(RF_ShutdownList_t **, RF_Raid_t *, RF_Config_t *);
    132    1.1     oster 
    133  1.126       mrg rf_declare_mutex2(rf_printf_mutex);	/* debug only:  avoids interleaved
    134    1.6     oster 					 * printfs by different stripes */
    135    1.1     oster 
    136  1.127       mrg #define SIGNAL_QUIESCENT_COND(_raid_) \
    137  1.127       mrg 	rf_broadcast_cond2((_raid_)->access_suspend_cv)
    138    1.1     oster #define WAIT_FOR_QUIESCENCE(_raid_) \
    139  1.127       mrg 	rf_wait_cond2((_raid_)->access_suspend_cv, \
    140  1.127       mrg 		      (_raid_)->access_suspend_mutex)
    141    1.1     oster 
    142    1.9     oster static int configureCount = 0;	/* number of active configurations */
    143    1.9     oster static int isconfigged = 0;	/* is basic raidframe (non per-array)
    144  1.116     oster 				 * stuff configured */
    145  1.125       mrg static rf_declare_mutex2(configureMutex); /* used to lock the configuration
    146  1.125       mrg 					   * stuff */
    147    1.9     oster static RF_ShutdownList_t *globalShutdown;	/* non array-specific
    148    1.9     oster 						 * stuff */
    149    1.1     oster 
    150  1.138     oster static int rf_ConfigureRDFreeList(RF_ShutdownList_t ** listp, RF_Raid_t *raidPtr, RF_Config_t *cfgPtr);
    151  1.103     oster static int rf_AllocEmergBuffers(RF_Raid_t *);
    152  1.103     oster static void rf_FreeEmergBuffers(RF_Raid_t *);
    153  1.130       mrg static void rf_destroy_mutex_cond(RF_Raid_t *);
    154  1.130       mrg static void rf_alloc_mutex_cond(RF_Raid_t *);
    155    1.1     oster 
    156    1.1     oster /* called at system boot time */
    157  1.107     perry int
    158  1.132  pgoyette rf_BootRaidframe(bool boot)
    159    1.1     oster {
    160    1.1     oster 
    161  1.132  pgoyette 	if (boot) {
    162  1.132  pgoyette 		if (raidframe_booted)
    163  1.132  pgoyette 			return (EBUSY);
    164  1.132  pgoyette 		raidframe_booted = 1;
    165  1.132  pgoyette 		rf_init_mutex2(configureMutex, IPL_NONE);
    166  1.132  pgoyette  		configureCount = 0;
    167  1.132  pgoyette 		isconfigged = 0;
    168  1.132  pgoyette 		globalShutdown = NULL;
    169  1.132  pgoyette 	} else {
    170  1.132  pgoyette 		rf_destroy_mutex2(configureMutex);
    171  1.132  pgoyette 		raidframe_booted = 0;
    172  1.132  pgoyette 	}
    173    1.6     oster 	return (0);
    174    1.1     oster }
    175    1.1     oster 
    176    1.1     oster /*
    177    1.1     oster  * Called whenever an array is shutdown
    178    1.1     oster  */
    179  1.107     perry static void
    180  1.121    cegger rf_UnconfigureArray(void)
    181    1.1     oster {
    182    1.1     oster 
    183  1.125       mrg 	rf_lock_mutex2(configureMutex);
    184    1.6     oster 	if (--configureCount == 0) {	/* if no active configurations, shut
    185    1.6     oster 					 * everything down */
    186  1.129      yamt 		rf_destroy_mutex2(rf_printf_mutex);
    187    1.6     oster 		isconfigged = 0;
    188   1.92     oster 		rf_ShutdownList(&globalShutdown);
    189    1.6     oster 
    190    1.6     oster 		/*
    191    1.6     oster 	         * We must wait until now, because the AllocList module
    192    1.6     oster 	         * uses the DebugMem module.
    193    1.6     oster 	         */
    194   1.60     oster #if RF_DEBUG_MEM
    195    1.6     oster 		if (rf_memDebug)
    196    1.6     oster 			rf_print_unfreed();
    197   1.60     oster #endif
    198    1.6     oster 	}
    199  1.125       mrg 	rf_unlock_mutex2(configureMutex);
    200    1.9     oster }
    201    1.9     oster 
    202    1.1     oster /*
    203    1.1     oster  * Called to shut down an array.
    204    1.1     oster  */
    205  1.107     perry int
    206   1.80     oster rf_Shutdown(RF_Raid_t *raidPtr)
    207    1.1     oster {
    208  1.100     oster 
    209    1.6     oster 	if (!raidPtr->valid) {
    210    1.6     oster 		RF_ERRORMSG("Attempt to shut down unconfigured RAIDframe driver.  Aborting shutdown\n");
    211    1.6     oster 		return (EINVAL);
    212    1.6     oster 	}
    213    1.6     oster 	/*
    214    1.6     oster          * wait for outstanding IOs to land
    215    1.6     oster          * As described in rf_raid.h, we use the rad_freelist lock
    216    1.6     oster          * to protect the per-array info about outstanding descs
    217    1.6     oster          * since we need to do freelist locking anyway, and this
    218    1.6     oster          * cuts down on the amount of serialization we've got going
    219    1.6     oster          * on.
    220    1.6     oster          */
    221  1.126       mrg 	rf_lock_mutex2(raidPtr->rad_lock);
    222    1.6     oster 	if (raidPtr->waitShutdown) {
    223  1.126       mrg 		rf_unlock_mutex2(raidPtr->rad_lock);
    224    1.6     oster 		return (EBUSY);
    225    1.6     oster 	}
    226    1.6     oster 	raidPtr->waitShutdown = 1;
    227    1.6     oster 	while (raidPtr->nAccOutstanding) {
    228  1.126       mrg 		rf_wait_cond2(raidPtr->outstandingCond, raidPtr->rad_lock);
    229    1.6     oster 	}
    230   1.35     oster 
    231   1.35     oster 	/* Wait for any parity re-writes to stop... */
    232   1.35     oster 	while (raidPtr->parity_rewrite_in_progress) {
    233  1.120     oster 		printf("raid%d: Waiting for parity re-write to exit...\n",
    234  1.120     oster 		       raidPtr->raidid);
    235  1.134       mrg 		rf_wait_cond2(raidPtr->parity_rewrite_cv, raidPtr->rad_lock);
    236   1.35     oster 	}
    237  1.134       mrg 	rf_unlock_mutex2(raidPtr->rad_lock);
    238    1.6     oster 
    239  1.120     oster 	/* Wait for any reconstruction to stop... */
    240  1.128       mrg 	rf_lock_mutex2(raidPtr->mutex);
    241  1.120     oster 	while (raidPtr->reconInProgress) {
    242  1.120     oster 		printf("raid%d: Waiting for reconstruction to stop...\n",
    243  1.120     oster 		       raidPtr->raidid);
    244  1.128       mrg 		rf_wait_cond2(raidPtr->waitForReconCond, raidPtr->mutex);
    245  1.120     oster 	}
    246  1.128       mrg 	rf_unlock_mutex2(raidPtr->mutex);
    247  1.120     oster 
    248    1.6     oster 	raidPtr->valid = 0;
    249    1.6     oster 
    250  1.122       jld 	if (raidPtr->parity_map != NULL)
    251  1.122       jld 		rf_paritymap_detach(raidPtr);
    252  1.122       jld 
    253   1.37     oster 	rf_update_component_labels(raidPtr, RF_FINAL_COMPONENT_UPDATE);
    254    1.6     oster 
    255    1.7     oster 	rf_UnconfigureVnodes(raidPtr);
    256    1.7     oster 
    257  1.103     oster 	rf_FreeEmergBuffers(raidPtr);
    258  1.100     oster 
    259    1.7     oster 	rf_ShutdownList(&raidPtr->shutdownList);
    260    1.7     oster 
    261  1.130       mrg 	rf_destroy_mutex_cond(raidPtr);
    262  1.128       mrg 
    263    1.7     oster 	rf_UnconfigureArray();
    264    1.7     oster 
    265    1.7     oster 	return (0);
    266    1.7     oster }
    267    1.1     oster 
    268    1.6     oster 
    269    1.1     oster #define DO_INIT_CONFIGURE(f) { \
    270    1.1     oster 	rc = f (&globalShutdown); \
    271    1.1     oster 	if (rc) { \
    272    1.1     oster 		RF_ERRORMSG2("RAIDFRAME: failed %s with %d\n", RF_STRING(f), rc); \
    273    1.1     oster 		rf_ShutdownList(&globalShutdown); \
    274    1.1     oster 		configureCount--; \
    275  1.125       mrg 		rf_unlock_mutex2(configureMutex); \
    276  1.129      yamt 		rf_destroy_mutex2(rf_printf_mutex); \
    277    1.1     oster 		return(rc); \
    278    1.1     oster 	} \
    279    1.1     oster }
    280    1.1     oster 
    281    1.1     oster #define DO_RAID_FAIL() { \
    282   1.12     oster 	rf_UnconfigureVnodes(raidPtr); \
    283  1.103     oster 	rf_FreeEmergBuffers(raidPtr); \
    284    1.1     oster 	rf_ShutdownList(&raidPtr->shutdownList); \
    285    1.1     oster 	rf_UnconfigureArray(); \
    286  1.130       mrg 	rf_destroy_mutex_cond(raidPtr); \
    287    1.1     oster }
    288    1.1     oster 
    289    1.1     oster #define DO_RAID_INIT_CONFIGURE(f) { \
    290    1.1     oster 	rc = f (&raidPtr->shutdownList, raidPtr, cfgPtr); \
    291    1.1     oster 	if (rc) { \
    292    1.1     oster 		RF_ERRORMSG2("RAIDFRAME: failed %s with %d\n", RF_STRING(f), rc); \
    293    1.1     oster 		DO_RAID_FAIL(); \
    294    1.1     oster 		return(rc); \
    295    1.1     oster 	} \
    296    1.1     oster }
    297    1.1     oster 
    298  1.107     perry int
    299   1.80     oster rf_Configure(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr, RF_AutoConfig_t *ac)
    300    1.6     oster {
    301   1.72     oster 	RF_RowCol_t col;
    302  1.103     oster 	int rc;
    303  1.137       mrg 	bool swapped = false;
    304  1.137       mrg 	bool first = true;
    305    1.6     oster 
    306  1.125       mrg 	rf_lock_mutex2(configureMutex);
    307    1.6     oster 	configureCount++;
    308    1.6     oster 	if (isconfigged == 0) {
    309  1.126       mrg 		rf_init_mutex2(rf_printf_mutex, IPL_VM);
    310   1.75     oster 
    311    1.6     oster 		/* initialize globals */
    312    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureAllocList);
    313   1.28     oster 
    314    1.6     oster 		/*
    315   1.28     oster 	         * Yes, this does make debugging general to the whole
    316  1.107     perry 	         * system instead of being array specific. Bummer, drag.
    317   1.28     oster 		 */
    318    1.6     oster 		rf_ConfigureDebug(cfgPtr);
    319    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureDebugMem);
    320   1.87     oster #if RF_ACC_TRACE > 0
    321    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureAccessTrace);
    322   1.87     oster #endif
    323    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureNWayXor);
    324    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureDAGFuncs);
    325    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureCopyback);
    326    1.6     oster 		isconfigged = 1;
    327    1.6     oster 	}
    328  1.125       mrg 	rf_unlock_mutex2(configureMutex);
    329    1.6     oster 
    330  1.130       mrg 	rf_alloc_mutex_cond(raidPtr);
    331  1.130       mrg 
    332    1.6     oster 	/* set up the cleanup list.  Do this after ConfigureDebug so that
    333    1.6     oster 	 * value of memDebug will be set */
    334    1.6     oster 
    335    1.6     oster 	rf_MakeAllocList(raidPtr->cleanupList);
    336    1.6     oster 	if (raidPtr->cleanupList == NULL) {
    337    1.6     oster 		DO_RAID_FAIL();
    338    1.6     oster 		return (ENOMEM);
    339    1.6     oster 	}
    340   1.86     oster 	rf_ShutdownCreate(&raidPtr->shutdownList,
    341   1.86     oster 			  (void (*) (void *)) rf_FreeAllocList,
    342   1.86     oster 			  raidPtr->cleanupList);
    343   1.86     oster 
    344  1.140       mrg 	KASSERT(cfgPtr->numCol < RF_MAXCOL);
    345  1.140       mrg 	KASSERT(cfgPtr->numCol >= 0);
    346  1.140       mrg 	KASSERT(cfgPtr->numSpare < RF_MAXSPARE);
    347  1.140       mrg 	KASSERT(cfgPtr->numSpare >= 0);
    348  1.140       mrg 
    349    1.6     oster 	raidPtr->numCol = cfgPtr->numCol;
    350    1.6     oster 	raidPtr->numSpare = cfgPtr->numSpare;
    351  1.141     oster 	raidPtr->maxQueue = cfgPtr->numSpare;
    352    1.6     oster 
    353   1.72     oster 	raidPtr->status = rf_rs_optimal;
    354   1.72     oster 	raidPtr->reconControl = NULL;
    355  1.107     perry 
    356  1.138     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureMapModule);
    357  1.138     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureReconEvent);
    358  1.138     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureCallback);
    359  1.138     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureRDFreeList);
    360  1.138     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureStripeLockFreeList);
    361  1.138     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureMCPair);
    362  1.138     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureDAGs);
    363  1.138     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureReconstruction);
    364  1.138     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureDiskQueueSystem);
    365  1.138     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigurePSStatus);
    366  1.138     oster 
    367    1.6     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureEngine);
    368    1.6     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureStripeLocks);
    369    1.6     oster 
    370    1.6     oster 	raidPtr->nAccOutstanding = 0;
    371    1.6     oster 	raidPtr->waitShutdown = 0;
    372    1.6     oster 
    373   1.28     oster 	if (ac!=NULL) {
    374   1.28     oster 		/* We have an AutoConfig structure..  Don't do the
    375   1.28     oster 		   normal disk configuration... call the auto config
    376   1.28     oster 		   stuff */
    377   1.28     oster 		rf_AutoConfigureDisks(raidPtr, cfgPtr, ac);
    378   1.28     oster 	} else {
    379   1.28     oster 		DO_RAID_INIT_CONFIGURE(rf_ConfigureDisks);
    380   1.28     oster 		DO_RAID_INIT_CONFIGURE(rf_ConfigureSpareDisks);
    381   1.28     oster 	}
    382    1.6     oster 	/* do this after ConfigureDisks & ConfigureSpareDisks to be sure dev
    383    1.6     oster 	 * no. is set */
    384    1.6     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureDiskQueues);
    385    1.6     oster 
    386    1.6     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureLayout);
    387    1.6     oster 
    388  1.138     oster 
    389  1.138     oster 
    390  1.138     oster 
    391  1.110     oster 	/* Initialize per-RAID PSS bits */
    392  1.110     oster 	rf_InitPSStatus(raidPtr);
    393    1.6     oster 
    394   1.82     oster #if RF_INCLUDE_CHAINDECLUSTER > 0
    395   1.72     oster 	for (col = 0; col < raidPtr->numCol; col++) {
    396   1.72     oster 		/*
    397   1.72     oster 		 * XXX better distribution
    398   1.72     oster 		 */
    399   1.72     oster 		raidPtr->hist_diskreq[col] = 0;
    400    1.6     oster 	}
    401   1.82     oster #endif
    402   1.30     oster 	raidPtr->numNewFailures = 0;
    403   1.28     oster 	raidPtr->copyback_in_progress = 0;
    404   1.28     oster 	raidPtr->parity_rewrite_in_progress = 0;
    405  1.141     oster 	raidPtr->changing_components = 0;
    406   1.28     oster 	raidPtr->recon_in_progress = 0;
    407  1.128       mrg 
    408   1.29     oster 	raidPtr->maxOutstanding = cfgPtr->maxOutstandingDiskReqs;
    409   1.29     oster 
    410  1.107     perry 	/* autoconfigure and root_partition will actually get filled in
    411   1.29     oster 	   after the config is done */
    412   1.29     oster 	raidPtr->autoconfigure = 0;
    413   1.29     oster 	raidPtr->root_partition = 0;
    414   1.29     oster 	raidPtr->last_unit = raidPtr->raidid;
    415   1.29     oster 	raidPtr->config_order = 0;
    416    1.6     oster 
    417    1.6     oster 	if (rf_keepAccTotals) {
    418    1.6     oster 		raidPtr->keep_acc_totals = 1;
    419    1.6     oster 	}
    420    1.1     oster 
    421   1.97     oster 	/* Allocate a bunch of buffers to be used in low-memory conditions */
    422   1.97     oster 	raidPtr->iobuf = NULL;
    423  1.103     oster 
    424  1.107     perry 	rc = rf_AllocEmergBuffers(raidPtr);
    425  1.103     oster 	if (rc) {
    426  1.103     oster 		printf("raid%d: Unable to allocate emergency buffers.\n",
    427  1.103     oster 		       raidPtr->raidid);
    428  1.103     oster 		DO_RAID_FAIL();
    429  1.103     oster 		return(rc);
    430  1.103     oster 	}
    431  1.103     oster 
    432  1.122       jld 	/* Set up parity map stuff, if applicable. */
    433  1.122       jld #ifndef RF_NO_PARITY_MAP
    434  1.122       jld 	rf_paritymap_attach(raidPtr, cfgPtr->force);
    435  1.122       jld #endif
    436  1.122       jld 
    437  1.103     oster 	raidPtr->valid = 1;
    438  1.103     oster 
    439  1.103     oster 	printf("raid%d: %s\n", raidPtr->raidid,
    440  1.103     oster 	       raidPtr->Layout.map->configName);
    441  1.103     oster 	printf("raid%d: Components:", raidPtr->raidid);
    442  1.103     oster 
    443  1.103     oster 	for (col = 0; col < raidPtr->numCol; col++) {
    444  1.137       mrg 		RF_ComponentLabel_t *clabel;
    445  1.137       mrg 		bool compswapped;
    446  1.137       mrg 
    447  1.103     oster 		printf(" %s", raidPtr->Disks[col].devname);
    448  1.103     oster 		if (RF_DEAD_DISK(raidPtr->Disks[col].status)) {
    449  1.103     oster 			printf("[**FAILED**]");
    450  1.103     oster 		}
    451  1.137       mrg 		clabel = raidget_component_label(raidPtr, col);
    452  1.137       mrg 		compswapped = clabel->version ==
    453  1.137       mrg 			      bswap32(RF_COMPONENT_LABEL_VERSION);
    454  1.137       mrg 		if (first)
    455  1.137       mrg 			swapped = compswapped;
    456  1.137       mrg 		else if (swapped != compswapped)
    457  1.137       mrg 			printf("raid%d: Component %d has different endian "
    458  1.137       mrg 			       "than first component.", raidPtr->raidid, col);
    459  1.103     oster 	}
    460  1.103     oster 	printf("\n");
    461  1.117  sborrill 	printf("raid%d: Total Sectors: %" PRIu64 " (%" PRIu64 " MB)\n",
    462  1.103     oster 	       raidPtr->raidid,
    463  1.117  sborrill 	       raidPtr->totalSectors,
    464  1.117  sborrill 	       (raidPtr->totalSectors / 1024 *
    465  1.103     oster 				(1 << raidPtr->logBytesPerSector) / 1024));
    466  1.137       mrg 	if (swapped)
    467  1.137       mrg 		printf("raid%d: Using swapped-endian component labels.\n",
    468  1.137       mrg 		    raidPtr->raidid);
    469  1.103     oster 
    470  1.103     oster 	return (0);
    471  1.103     oster }
    472  1.103     oster 
    473  1.103     oster 
    474  1.103     oster /*
    475  1.103     oster 
    476  1.103     oster   Routines to allocate and free the "emergency buffers" for a given
    477  1.103     oster   RAID set.  These emergency buffers will be used when the kernel runs
    478  1.107     perry   out of kernel memory.
    479  1.107     perry 
    480  1.103     oster  */
    481  1.103     oster 
    482  1.107     perry static int
    483  1.103     oster rf_AllocEmergBuffers(RF_Raid_t *raidPtr)
    484  1.103     oster {
    485  1.103     oster 	void *tmpbuf;
    486  1.103     oster 	RF_VoidPointerListElem_t *vple;
    487  1.103     oster 	int i;
    488  1.103     oster 
    489   1.97     oster 	/* XXX next line needs tuning... */
    490   1.97     oster 	raidPtr->numEmergencyBuffers = 10 * raidPtr->numCol;
    491   1.97     oster #if DEBUG
    492   1.97     oster 	printf("raid%d: allocating %d buffers of %d bytes.\n",
    493   1.97     oster 	       raidPtr->raidid,
    494  1.107     perry 	       raidPtr->numEmergencyBuffers,
    495  1.107     perry 	       (int)(raidPtr->Layout.sectorsPerStripeUnit <<
    496   1.97     oster 	       raidPtr->logBytesPerSector));
    497   1.97     oster #endif
    498   1.97     oster 	for (i = 0; i < raidPtr->numEmergencyBuffers; i++) {
    499  1.107     perry 		tmpbuf = malloc( raidPtr->Layout.sectorsPerStripeUnit <<
    500  1.107     perry 				 raidPtr->logBytesPerSector,
    501  1.111     oster 				 M_RAIDFRAME, M_WAITOK);
    502   1.97     oster 		if (tmpbuf) {
    503  1.138     oster 			vple = rf_AllocVPListElem(raidPtr);
    504   1.99     oster 			vple->p= tmpbuf;
    505   1.99     oster 			vple->next = raidPtr->iobuf;
    506   1.99     oster 			raidPtr->iobuf = vple;
    507   1.97     oster 			raidPtr->iobuf_count++;
    508   1.97     oster 		} else {
    509   1.97     oster 			printf("raid%d: failed to allocate emergency buffer!\n",
    510   1.97     oster 			       raidPtr->raidid);
    511  1.111     oster 			return 1;
    512   1.97     oster 		}
    513   1.97     oster 	}
    514   1.97     oster 
    515   1.99     oster 	/* XXX next line needs tuning too... */
    516   1.99     oster 	raidPtr->numEmergencyStripeBuffers = 10;
    517   1.99     oster         for (i = 0; i < raidPtr->numEmergencyStripeBuffers; i++) {
    518   1.99     oster                 tmpbuf = malloc( raidPtr->numCol * (raidPtr->Layout.sectorsPerStripeUnit <<
    519   1.99     oster                                  raidPtr->logBytesPerSector),
    520  1.111     oster                                  M_RAIDFRAME, M_WAITOK);
    521   1.99     oster                 if (tmpbuf) {
    522  1.138     oster                         vple = rf_AllocVPListElem(raidPtr);
    523   1.99     oster                         vple->p= tmpbuf;
    524   1.99     oster                         vple->next = raidPtr->stripebuf;
    525   1.99     oster                         raidPtr->stripebuf = vple;
    526   1.99     oster                         raidPtr->stripebuf_count++;
    527   1.99     oster                 } else {
    528   1.99     oster                         printf("raid%d: failed to allocate emergency stripe buffer!\n",
    529   1.99     oster                                raidPtr->raidid);
    530  1.111     oster 			return 1;
    531   1.99     oster                 }
    532   1.99     oster         }
    533  1.107     perry 
    534  1.103     oster 	return (0);
    535  1.103     oster }
    536   1.99     oster 
    537  1.103     oster static void
    538  1.103     oster rf_FreeEmergBuffers(RF_Raid_t *raidPtr)
    539  1.103     oster {
    540  1.103     oster 	RF_VoidPointerListElem_t *tmp;
    541   1.99     oster 
    542  1.103     oster 	/* Free the emergency IO buffers */
    543  1.103     oster 	while (raidPtr->iobuf != NULL) {
    544  1.103     oster 		tmp = raidPtr->iobuf;
    545  1.103     oster 		raidPtr->iobuf = raidPtr->iobuf->next;
    546  1.103     oster 		free(tmp->p, M_RAIDFRAME);
    547  1.138     oster 		rf_FreeVPListElem(raidPtr,tmp);
    548  1.103     oster 	}
    549   1.52     oster 
    550  1.103     oster 	/* Free the emergency stripe buffers */
    551  1.103     oster 	while (raidPtr->stripebuf != NULL) {
    552  1.103     oster 		tmp = raidPtr->stripebuf;
    553  1.103     oster 		raidPtr->stripebuf = raidPtr->stripebuf->next;
    554  1.103     oster 		free(tmp->p, M_RAIDFRAME);
    555  1.138     oster 		rf_FreeVPListElem(raidPtr, tmp);
    556   1.52     oster 	}
    557  1.103     oster }
    558   1.50     oster 
    559    1.1     oster 
    560  1.107     perry static void
    561  1.138     oster rf_ShutdownRDFreeList(void *arg)
    562    1.1     oster {
    563  1.138     oster 	RF_Raid_t *raidPtr;
    564  1.138     oster 
    565  1.138     oster 	raidPtr = (RF_Raid_t *) arg;
    566  1.138     oster 
    567  1.138     oster 	pool_destroy(&raidPtr->pools.rad);
    568    1.1     oster }
    569    1.1     oster 
    570  1.107     perry static int
    571  1.138     oster rf_ConfigureRDFreeList(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
    572  1.138     oster 		       RF_Config_t *cfgPtr)
    573    1.1     oster {
    574    1.1     oster 
    575  1.138     oster 	rf_pool_init(raidPtr, raidPtr->poolNames.rad, &raidPtr->pools.rad, sizeof(RF_RaidAccessDesc_t),
    576  1.138     oster 		     "rad", RF_MIN_FREE_RAD, RF_MAX_FREE_RAD);
    577  1.138     oster 	rf_ShutdownCreate(listp, rf_ShutdownRDFreeList, raidPtr);
    578    1.6     oster 	return (0);
    579    1.6     oster }
    580    1.6     oster 
    581    1.6     oster RF_RaidAccessDesc_t *
    582   1.80     oster rf_AllocRaidAccDesc(RF_Raid_t *raidPtr, RF_IoType_t type,
    583   1.80     oster 		    RF_RaidAddr_t raidAddress, RF_SectorCount_t numBlocks,
    584  1.114  christos 		    void *bufPtr, void *bp, RF_RaidAccessFlags_t flags,
    585  1.102  drochner 		    const RF_AccessState_t *states)
    586    1.6     oster {
    587    1.6     oster 	RF_RaidAccessDesc_t *desc;
    588    1.6     oster 
    589  1.138     oster 	desc = pool_get(&raidPtr->pools.rad, PR_WAITOK);
    590   1.73     oster 
    591  1.126       mrg 	rf_lock_mutex2(raidPtr->rad_lock);
    592    1.6     oster 	if (raidPtr->waitShutdown) {
    593    1.6     oster 		/*
    594    1.6     oster 	         * Actually, we're shutting the array down. Free the desc
    595    1.6     oster 	         * and return NULL.
    596    1.6     oster 	         */
    597   1.73     oster 
    598  1.126       mrg 		rf_unlock_mutex2(raidPtr->rad_lock);
    599  1.138     oster 		pool_put(&raidPtr->pools.rad, desc);
    600    1.6     oster 		return (NULL);
    601    1.6     oster 	}
    602    1.6     oster 	raidPtr->nAccOutstanding++;
    603   1.73     oster 
    604  1.126       mrg 	rf_unlock_mutex2(raidPtr->rad_lock);
    605    1.6     oster 
    606    1.6     oster 	desc->raidPtr = (void *) raidPtr;
    607    1.6     oster 	desc->type = type;
    608    1.6     oster 	desc->raidAddress = raidAddress;
    609    1.6     oster 	desc->numBlocks = numBlocks;
    610    1.6     oster 	desc->bufPtr = bufPtr;
    611    1.6     oster 	desc->bp = bp;
    612    1.6     oster 	desc->flags = flags;
    613    1.6     oster 	desc->states = states;
    614    1.6     oster 	desc->state = 0;
    615   1.99     oster 	desc->dagList = NULL;
    616    1.6     oster 
    617    1.6     oster 	desc->status = 0;
    618  1.105     oster 	desc->numRetries = 0;
    619   1.87     oster #if RF_ACC_TRACE > 0
    620  1.135  christos 	memset(&desc->tracerec, 0, sizeof(desc->tracerec));
    621   1.87     oster #endif
    622   1.41     oster 	desc->callbackFunc = NULL;
    623   1.41     oster 	desc->callbackArg = NULL;
    624    1.6     oster 	desc->next = NULL;
    625   1.99     oster 	desc->iobufs = NULL;
    626   1.99     oster 	desc->stripebufs = NULL;
    627   1.99     oster 
    628    1.6     oster 	return (desc);
    629    1.6     oster }
    630    1.6     oster 
    631  1.107     perry void
    632   1.80     oster rf_FreeRaidAccDesc(RF_RaidAccessDesc_t *desc)
    633    1.6     oster {
    634    1.6     oster 	RF_Raid_t *raidPtr = desc->raidPtr;
    635   1.85     oster 	RF_DagList_t *dagList, *temp;
    636   1.99     oster 	RF_VoidPointerListElem_t *tmp;
    637    1.6     oster 
    638    1.6     oster 	RF_ASSERT(desc);
    639    1.6     oster 
    640   1.85     oster 	/* Cleanup the dagList(s) */
    641   1.85     oster 	dagList = desc->dagList;
    642   1.85     oster 	while(dagList != NULL) {
    643   1.85     oster 		temp = dagList;
    644   1.85     oster 		dagList = dagList->next;
    645  1.138     oster 		rf_FreeDAGList(raidPtr, temp);
    646   1.85     oster 	}
    647   1.85     oster 
    648   1.99     oster 	while (desc->iobufs) {
    649   1.99     oster 		tmp = desc->iobufs;
    650   1.99     oster 		desc->iobufs = desc->iobufs->next;
    651   1.99     oster 		rf_FreeIOBuffer(raidPtr, tmp);
    652   1.99     oster 	}
    653   1.99     oster 
    654   1.99     oster 	while (desc->stripebufs) {
    655   1.99     oster 		tmp = desc->stripebufs;
    656   1.99     oster 		desc->stripebufs = desc->stripebufs->next;
    657   1.99     oster 		rf_FreeStripeBuffer(raidPtr, tmp);
    658   1.99     oster 	}
    659   1.99     oster 
    660  1.138     oster 	pool_put(&raidPtr->pools.rad, desc);
    661  1.126       mrg 	rf_lock_mutex2(raidPtr->rad_lock);
    662    1.6     oster 	raidPtr->nAccOutstanding--;
    663    1.6     oster 	if (raidPtr->waitShutdown) {
    664  1.126       mrg 		rf_signal_cond2(raidPtr->outstandingCond);
    665    1.6     oster 	}
    666  1.126       mrg 	rf_unlock_mutex2(raidPtr->rad_lock);
    667    1.1     oster }
    668    1.1     oster /*********************************************************************
    669    1.1     oster  * Main routine for performing an access.
    670    1.1     oster  * Accesses are retried until a DAG can not be selected.  This occurs
    671    1.1     oster  * when either the DAG library is incomplete or there are too many
    672    1.1     oster  * failures in a parity group.
    673   1.80     oster  *
    674  1.139     oster  * type should be read or write.  bp_in is a buf pointer.  void *to
    675  1.139     oster  * facilitate ignoring it outside the kernel
    676    1.1     oster  ********************************************************************/
    677  1.107     perry int
    678  1.139     oster rf_DoAccess(RF_Raid_t * raidPtr, RF_IoType_t type, RF_RaidAddr_t raidAddress, RF_SectorCount_t numBlocks,
    679  1.114  christos 	    void *bufPtr, struct buf *bp, RF_RaidAccessFlags_t flags)
    680    1.1     oster {
    681    1.6     oster 	RF_RaidAccessDesc_t *desc;
    682  1.114  christos 	void *lbufPtr = bufPtr;
    683    1.6     oster 
    684    1.6     oster 	raidAddress += rf_raidSectorOffset;
    685    1.6     oster 
    686   1.61     oster #if RF_ACCESS_DEBUG
    687    1.6     oster 	if (rf_accessDebug) {
    688    1.1     oster 
    689    1.6     oster 		printf("logBytes is: %d %d %d\n", raidPtr->raidid,
    690    1.6     oster 		    raidPtr->logBytesPerSector,
    691    1.6     oster 		    (int) rf_RaidAddressToByte(raidPtr, numBlocks));
    692   1.22     oster 		printf("raid%d: %s raidAddr %d (stripeid %d-%d) numBlocks %d (%d bytes) buf 0x%lx\n", raidPtr->raidid,
    693    1.6     oster 		    (type == RF_IO_TYPE_READ) ? "READ" : "WRITE", (int) raidAddress,
    694    1.6     oster 		    (int) rf_RaidAddressToStripeID(&raidPtr->Layout, raidAddress),
    695    1.6     oster 		    (int) rf_RaidAddressToStripeID(&raidPtr->Layout, raidAddress + numBlocks - 1),
    696    1.6     oster 		    (int) numBlocks,
    697    1.6     oster 		    (int) rf_RaidAddressToByte(raidPtr, numBlocks),
    698    1.6     oster 		    (long) bufPtr);
    699    1.6     oster 	}
    700   1.61     oster #endif
    701    1.1     oster 
    702    1.6     oster 	desc = rf_AllocRaidAccDesc(raidPtr, type, raidAddress,
    703   1.41     oster 	    numBlocks, lbufPtr, bp, flags, raidPtr->Layout.map->states);
    704    1.1     oster 
    705    1.6     oster 	if (desc == NULL) {
    706    1.6     oster 		return (ENOMEM);
    707    1.6     oster 	}
    708   1.87     oster #if RF_ACC_TRACE > 0
    709    1.6     oster 	RF_ETIMER_START(desc->tracerec.tot_timer);
    710   1.87     oster #endif
    711    1.3  explorer 
    712  1.122       jld 	if (raidPtr->parity_map != NULL &&
    713  1.122       jld 	    type == RF_IO_TYPE_WRITE)
    714  1.122       jld 		rf_paritymap_begin(raidPtr->parity_map, raidAddress,
    715  1.122       jld 		    numBlocks);
    716  1.122       jld 
    717    1.6     oster 	rf_ContinueRaidAccess(desc);
    718    1.1     oster 
    719    1.6     oster 	return (0);
    720    1.1     oster }
    721   1.46     oster #if 0
    722    1.1     oster /* force the array into reconfigured mode without doing reconstruction */
    723  1.107     perry int
    724   1.80     oster rf_SetReconfiguredMode(RF_Raid_t *raidPtr, int col)
    725    1.6     oster {
    726    1.6     oster 	if (!(raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
    727    1.6     oster 		printf("Can't set reconfigured mode in dedicated-spare array\n");
    728    1.6     oster 		RF_PANIC();
    729    1.6     oster 	}
    730  1.128       mrg 	rf_lock_mutex2(raidPtr->mutex);
    731    1.6     oster 	raidPtr->numFailures++;
    732   1.72     oster 	raidPtr->Disks[col].status = rf_ds_dist_spared;
    733   1.72     oster 	raidPtr->status = rf_rs_reconfigured;
    734   1.37     oster 	rf_update_component_labels(raidPtr, RF_NORMAL_COMPONENT_UPDATE);
    735    1.6     oster 	/* install spare table only if declustering + distributed sparing
    736    1.6     oster 	 * architecture. */
    737    1.6     oster 	if (raidPtr->Layout.map->flags & RF_BD_DECLUSTERED)
    738   1.72     oster 		rf_InstallSpareTable(raidPtr, col);
    739  1.128       mrg 	rf_unlock_mutex2(raidPtr->mutex);
    740    1.6     oster 	return (0);
    741    1.1     oster }
    742   1.46     oster #endif
    743    1.1     oster 
    744  1.107     perry int
    745   1.80     oster rf_FailDisk(RF_Raid_t *raidPtr, int fcol, int initRecon)
    746    1.6     oster {
    747   1.98     oster 
    748   1.98     oster 	/* need to suspend IO's here -- if there are DAGs in flight
    749  1.107     perry 	   and we pull the rug out from under ci_vp, Bad Things
    750   1.98     oster 	   can happen.  */
    751   1.98     oster 
    752   1.98     oster 	rf_SuspendNewRequestsAndWait(raidPtr);
    753   1.98     oster 
    754  1.128       mrg 	rf_lock_mutex2(raidPtr->mutex);
    755   1.72     oster 	if (raidPtr->Disks[fcol].status != rf_ds_failed) {
    756   1.68     oster 		/* must be failing something that is valid, or else it's
    757  1.107     perry 		   already marked as failed (in which case we don't
    758   1.68     oster 		   want to mark it failed again!) */
    759   1.68     oster 		raidPtr->numFailures++;
    760   1.72     oster 		raidPtr->Disks[fcol].status = rf_ds_failed;
    761  1.107     perry 		raidPtr->status = rf_rs_degraded;
    762   1.68     oster 	}
    763  1.128       mrg 	rf_unlock_mutex2(raidPtr->mutex);
    764  1.107     perry 
    765   1.37     oster 	rf_update_component_labels(raidPtr, RF_NORMAL_COMPONENT_UPDATE);
    766  1.107     perry 
    767  1.107     perry 	/* Close the component, so that it's not "locked" if someone
    768   1.56     oster 	   else want's to use it! */
    769   1.56     oster 
    770   1.72     oster 	rf_close_component(raidPtr, raidPtr->raid_cinfo[fcol].ci_vp,
    771   1.72     oster 			   raidPtr->Disks[fcol].auto_configured);
    772   1.65     oster 
    773  1.128       mrg 	rf_lock_mutex2(raidPtr->mutex);
    774   1.72     oster 	raidPtr->raid_cinfo[fcol].ci_vp = NULL;
    775   1.56     oster 
    776  1.107     perry 	/* Need to mark the component as not being auto_configured
    777   1.56     oster 	   (in case it was previously). */
    778   1.56     oster 
    779   1.72     oster 	raidPtr->Disks[fcol].auto_configured = 0;
    780  1.128       mrg 	rf_unlock_mutex2(raidPtr->mutex);
    781   1.98     oster 	/* now we can allow IO to continue -- we'll be suspending it
    782   1.98     oster 	   again in rf_ReconstructFailedDisk() if we have to.. */
    783   1.98     oster 
    784   1.98     oster 	rf_ResumeNewRequests(raidPtr);
    785   1.56     oster 
    786    1.6     oster 	if (initRecon)
    787   1.72     oster 		rf_ReconstructFailedDisk(raidPtr, fcol);
    788    1.6     oster 	return (0);
    789    1.1     oster }
    790    1.1     oster /* releases a thread that is waiting for the array to become quiesced.
    791    1.1     oster  * access_suspend_mutex should be locked upon calling this
    792    1.1     oster  */
    793  1.107     perry void
    794   1.80     oster rf_SignalQuiescenceLock(RF_Raid_t *raidPtr)
    795    1.6     oster {
    796   1.61     oster #if RF_DEBUG_QUIESCE
    797    1.6     oster 	if (rf_quiesceDebug) {
    798  1.107     perry 		printf("raid%d: Signalling quiescence lock\n",
    799   1.22     oster 		       raidPtr->raidid);
    800    1.6     oster 	}
    801   1.61     oster #endif
    802    1.6     oster 	raidPtr->access_suspend_release = 1;
    803    1.6     oster 
    804    1.6     oster 	if (raidPtr->waiting_for_quiescence) {
    805    1.6     oster 		SIGNAL_QUIESCENT_COND(raidPtr);
    806    1.6     oster 	}
    807    1.1     oster }
    808    1.1     oster /* suspends all new requests to the array.  No effect on accesses that are in flight.  */
    809  1.107     perry int
    810   1.80     oster rf_SuspendNewRequestsAndWait(RF_Raid_t *raidPtr)
    811    1.6     oster {
    812   1.61     oster #if RF_DEBUG_QUIESCE
    813    1.6     oster 	if (rf_quiesceDebug)
    814   1.53     oster 		printf("raid%d: Suspending new reqs\n", raidPtr->raidid);
    815   1.61     oster #endif
    816  1.127       mrg 	rf_lock_mutex2(raidPtr->access_suspend_mutex);
    817    1.6     oster 	raidPtr->accesses_suspended++;
    818    1.6     oster 	raidPtr->waiting_for_quiescence = (raidPtr->accs_in_flight == 0) ? 0 : 1;
    819    1.6     oster 
    820    1.6     oster 	if (raidPtr->waiting_for_quiescence) {
    821    1.6     oster 		raidPtr->access_suspend_release = 0;
    822    1.6     oster 		while (!raidPtr->access_suspend_release) {
    823   1.93     oster #if RF_DEBUG_QUIESCE
    824   1.53     oster 			printf("raid%d: Suspending: Waiting for Quiescence\n",
    825   1.53     oster 			       raidPtr->raidid);
    826   1.93     oster #endif
    827    1.6     oster 			WAIT_FOR_QUIESCENCE(raidPtr);
    828    1.6     oster 			raidPtr->waiting_for_quiescence = 0;
    829    1.6     oster 		}
    830    1.6     oster 	}
    831   1.93     oster #if RF_DEBUG_QUIESCE
    832   1.53     oster 	printf("raid%d: Quiescence reached..\n", raidPtr->raidid);
    833   1.93     oster #endif
    834    1.1     oster 
    835  1.127       mrg 	rf_unlock_mutex2(raidPtr->access_suspend_mutex);
    836    1.6     oster 	return (raidPtr->waiting_for_quiescence);
    837    1.1     oster }
    838    1.1     oster /* wake up everyone waiting for quiescence to be released */
    839  1.107     perry void
    840   1.80     oster rf_ResumeNewRequests(RF_Raid_t *raidPtr)
    841    1.6     oster {
    842  1.136  christos 	RF_CallbackFuncDesc_t *t, *cb;
    843    1.6     oster 
    844   1.61     oster #if RF_DEBUG_QUIESCE
    845    1.6     oster 	if (rf_quiesceDebug)
    846  1.116     oster 		printf("raid%d: Resuming new requests\n", raidPtr->raidid);
    847   1.61     oster #endif
    848    1.6     oster 
    849  1.127       mrg 	rf_lock_mutex2(raidPtr->access_suspend_mutex);
    850    1.6     oster 	raidPtr->accesses_suspended--;
    851    1.6     oster 	if (raidPtr->accesses_suspended == 0)
    852    1.6     oster 		cb = raidPtr->quiesce_wait_list;
    853    1.6     oster 	else
    854    1.6     oster 		cb = NULL;
    855    1.6     oster 	raidPtr->quiesce_wait_list = NULL;
    856  1.127       mrg 	rf_unlock_mutex2(raidPtr->access_suspend_mutex);
    857    1.6     oster 
    858    1.6     oster 	while (cb) {
    859    1.6     oster 		t = cb;
    860    1.6     oster 		cb = cb->next;
    861    1.6     oster 		(t->callbackFunc) (t->callbackArg);
    862  1.138     oster 		rf_FreeCallbackFuncDesc(raidPtr, t);
    863    1.6     oster 	}
    864    1.1     oster }
    865    1.1     oster /*****************************************************************************************
    866    1.1     oster  *
    867    1.1     oster  * debug routines
    868    1.1     oster  *
    869    1.1     oster  ****************************************************************************************/
    870    1.1     oster 
    871  1.107     perry static void
    872   1.80     oster set_debug_option(char *name, long val)
    873    1.6     oster {
    874    1.6     oster 	RF_DebugName_t *p;
    875    1.6     oster 
    876    1.6     oster 	for (p = rf_debugNames; p->name; p++) {
    877    1.6     oster 		if (!strcmp(p->name, name)) {
    878    1.6     oster 			*(p->ptr) = val;
    879    1.6     oster 			printf("[Set debug variable %s to %ld]\n", name, val);
    880    1.6     oster 			return;
    881    1.6     oster 		}
    882    1.6     oster 	}
    883    1.6     oster 	RF_ERRORMSG1("Unknown debug string \"%s\"\n", name);
    884    1.1     oster }
    885    1.1     oster 
    886    1.1     oster 
    887    1.1     oster /* would like to use sscanf here, but apparently not available in kernel */
    888    1.1     oster /*ARGSUSED*/
    889  1.107     perry static void
    890   1.80     oster rf_ConfigureDebug(RF_Config_t *cfgPtr)
    891    1.6     oster {
    892    1.6     oster 	char   *val_p, *name_p, *white_p;
    893    1.6     oster 	long    val;
    894    1.6     oster 	int     i;
    895    1.6     oster 
    896    1.6     oster 	rf_ResetDebugOptions();
    897  1.131   msaitoh 	for (i = 0; i < RF_MAXDBGV && cfgPtr->debugVars[i][0]; i++) {
    898    1.6     oster 		name_p = rf_find_non_white(&cfgPtr->debugVars[i][0]);
    899    1.6     oster 		white_p = rf_find_white(name_p);	/* skip to start of 2nd
    900    1.6     oster 							 * word */
    901    1.6     oster 		val_p = rf_find_non_white(white_p);
    902    1.6     oster 		if (*val_p == '0' && *(val_p + 1) == 'x')
    903    1.6     oster 			val = rf_htoi(val_p + 2);
    904    1.6     oster 		else
    905    1.6     oster 			val = rf_atoi(val_p);
    906    1.6     oster 		*white_p = '\0';
    907    1.6     oster 		set_debug_option(name_p, val);
    908    1.6     oster 	}
    909    1.1     oster }
    910   1.39     oster 
    911   1.39     oster void
    912  1.108  christos rf_print_panic_message(int line, const char *file)
    913   1.39     oster {
    914  1.133      maya 	kern_assert("raidframe error at line %d file %s", line, file);
    915   1.39     oster }
    916   1.39     oster 
    917   1.62     oster #ifdef RAID_DIAGNOSTIC
    918   1.39     oster void
    919  1.108  christos rf_print_assert_panic_message(int line,	const char *file, const char *condition)
    920   1.39     oster {
    921  1.133      maya 	kern_assert("raidframe error at line %d file %s (failed asserting %s)\n",
    922  1.133      maya 	    line, file, condition);
    923   1.58     oster }
    924   1.62     oster #endif
    925   1.58     oster 
    926   1.58     oster void
    927  1.108  christos rf_print_unable_to_init_mutex(const char *file, int line, int rc)
    928   1.58     oster {
    929   1.58     oster 	RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d\n",
    930   1.58     oster 		     file, line, rc);
    931   1.58     oster }
    932   1.58     oster 
    933   1.58     oster void
    934  1.108  christos rf_print_unable_to_add_shutdown(const char *file, int line, int rc)
    935   1.58     oster {
    936   1.58     oster 	RF_ERRORMSG3("Unable to add to shutdown list file %s line %d rc=%d\n",
    937   1.58     oster 		     file, line, rc);
    938    1.1     oster }
    939  1.130       mrg 
    940  1.130       mrg static void
    941  1.130       mrg rf_alloc_mutex_cond(RF_Raid_t *raidPtr)
    942  1.130       mrg {
    943  1.130       mrg 
    944  1.130       mrg 	rf_init_mutex2(raidPtr->mutex, IPL_VM);
    945  1.130       mrg 
    946  1.130       mrg 	rf_init_cond2(raidPtr->outstandingCond, "rfocond");
    947  1.134       mrg 	rf_init_cond2(raidPtr->parity_rewrite_cv, "rfprwshutdown");
    948  1.130       mrg 	rf_init_mutex2(raidPtr->rad_lock, IPL_VM);
    949  1.130       mrg 
    950  1.130       mrg 	rf_init_mutex2(raidPtr->access_suspend_mutex, IPL_VM);
    951  1.130       mrg 	rf_init_cond2(raidPtr->access_suspend_cv, "rfquiesce");
    952  1.130       mrg 
    953  1.130       mrg 	rf_init_cond2(raidPtr->waitForReconCond, "rfrcnw");
    954  1.130       mrg 
    955  1.141     oster 	rf_init_cond2(raidPtr->changing_components_cv, "raidhs");
    956  1.130       mrg }
    957  1.130       mrg 
    958  1.130       mrg static void
    959  1.130       mrg rf_destroy_mutex_cond(RF_Raid_t *raidPtr)
    960  1.130       mrg {
    961  1.130       mrg 
    962  1.130       mrg 	rf_destroy_cond2(raidPtr->waitForReconCond);
    963  1.141     oster 	rf_destroy_cond2(raidPtr->changing_components_cv);
    964  1.130       mrg 
    965  1.130       mrg 	rf_destroy_mutex2(raidPtr->access_suspend_mutex);
    966  1.130       mrg 	rf_destroy_cond2(raidPtr->access_suspend_cv);
    967  1.130       mrg 
    968  1.134       mrg 	rf_destroy_cond2(raidPtr->parity_rewrite_cv);
    969  1.130       mrg 	rf_destroy_cond2(raidPtr->outstandingCond);
    970  1.130       mrg 	rf_destroy_mutex2(raidPtr->rad_lock);
    971  1.130       mrg 
    972  1.130       mrg 	rf_destroy_mutex2(raidPtr->mutex);
    973  1.130       mrg }
    974