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