Changeset 974f9ba in mainline for uspace/srv/bd/hr/raid1.c
- Timestamp:
- 2025-07-04T19:42:41Z (3 weeks ago)
- Children:
- c76bf33
- Parents:
- 6aafb48
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/hr/raid1.c
r6aafb48 r974f9ba 57 57 58 58 static void hr_raid1_vol_state_eval_forced(hr_volume_t *); 59 static size_t hr_raid1_count_good_ extents(hr_volume_t *, uint64_t, size_t,59 static size_t hr_raid1_count_good_w_extents(hr_volume_t *, uint64_t, size_t, 60 60 uint64_t); 61 61 static errno_t hr_raid1_bd_op(hr_bd_op_type_t, hr_volume_t *, aoff64_t, size_t, … … 286 286 } 287 287 288 static size_t hr_raid1_count_good_ extents(hr_volume_t *vol, uint64_t ba,288 static size_t hr_raid1_count_good_w_extents(hr_volume_t *vol, uint64_t ba, 289 289 size_t cnt, uint64_t rebuild_blk) 290 290 { … … 304 304 } 305 305 306 #ifdef HR_RAID1_READ_STRATEGY_SPLIT 307 static size_t hr_raid1_count_good_r_extents(hr_volume_t *vol, uint64_t ba, 308 size_t cnt, uint64_t rebuild_blk) 309 { 310 assert(fibril_rwlock_is_locked(&vol->extents_lock)); 311 assert(fibril_rwlock_is_locked(&vol->states_lock)); 312 313 size_t count = 0; 314 for (size_t i = 0; i < vol->extent_no; i++) { 315 if (vol->extents[i].state == HR_EXT_ONLINE || 316 (vol->extents[i].state == HR_EXT_REBUILD && 317 rebuild_blk > ba + cnt - 1)) { 318 count++; 319 } 320 } 321 322 return count; 323 } 324 #endif 325 326 #ifdef HR_RAID1_READ_STRATEGY_CLOSEST 327 static size_t get_ext(hr_volume_t *vol, uint64_t ba, size_t cnt, 328 uint64_t rebuild_blk) 329 { 330 uint64_t closest_e; 331 uint64_t pos; 332 uint64_t mdiff = UINT64_MAX; 333 hr_ext_state_t state = vol->extents[0].state; 334 if (state != HR_EXT_ONLINE && 335 (state != HR_EXT_REBUILD || ba + cnt - 1 >= rebuild_blk)) { 336 closest_e = 1; 337 } else { 338 closest_e = 0; 339 pos = atomic_load_explicit(&vol->last_ext_pos_arr[0], 340 memory_order_relaxed); 341 mdiff = (pos > ba) ? pos - ba : ba - pos; 342 } 343 344 for (size_t e = 1; e < vol->extent_no; e++) { 345 state = vol->extents[e].state; 346 if (state != HR_EXT_ONLINE && 347 (state != HR_EXT_REBUILD || ba + cnt - 1 >= rebuild_blk)) { 348 continue; 349 } 350 351 pos = atomic_load_explicit(&vol->last_ext_pos_arr[e], 352 memory_order_relaxed); 353 uint64_t diff = (pos > ba) ? pos - ba : ba - pos; 354 if (diff < mdiff) { 355 mdiff = diff; 356 closest_e = e; 357 } 358 } 359 360 return closest_e; 361 } 362 363 #elif defined(HR_RAID1_READ_STRATEGY_ROUND_ROBIN) 364 365 static size_t get_ext(hr_volume_t *vol, uint64_t ba, size_t cnt, 366 uint64_t rebuild_blk) 367 { 368 size_t last_e; 369 size_t fail = 0; 370 371 while (true) { 372 last_e = atomic_fetch_add_explicit(&vol->last_ext_used, 1, 373 memory_order_relaxed); 374 last_e %= vol->extent_no; 375 376 hr_ext_state_t state = vol->extents[last_e].state; 377 if (state != HR_EXT_ONLINE && 378 (state != HR_EXT_REBUILD || ba + cnt - 1 >= rebuild_blk)) { 379 if (++fail >= vol->extent_no) 380 return vol->extent_no; 381 continue; 382 } 383 384 break; 385 } 386 387 return last_e; 388 } 389 390 #elif defined(HR_RAID1_READ_STRATEGY_FIRST) 391 392 static size_t get_ext(hr_volume_t *vol, uint64_t ba, size_t cnt, 393 uint64_t rebuild_blk) 394 { 395 for (size_t e = 0; e < vol->extent_no; e++) { 396 hr_ext_state_t state = vol->extents[e].state; 397 if (state != HR_EXT_ONLINE && 398 (state != HR_EXT_REBUILD || ba + cnt - 1 >= rebuild_blk)) { 399 continue; 400 } 401 402 return e; 403 } 404 return vol->extent_no; 405 } 406 407 #else 408 409 #if !defined(HR_RAID1_READ_STRATEGY_SPLIT) || \ 410 !defined(HR_RAID1_READ_STRATEGY_SPLIT_THRESHOLD) 411 #error "Some RAID 1 read strategy must be used" 412 #endif 413 414 #endif 415 416 static size_t hr_raid1_read(hr_volume_t *vol, uint64_t ba, size_t cnt, 417 void *data_read) 418 { 419 uint64_t rebuild_blk; 420 size_t successful = 0; 421 422 #if !defined(HR_RAID1_READ_STRATEGY_SPLIT) 423 errno_t rc; 424 425 rebuild_blk = atomic_load_explicit(&vol->rebuild_blk, 426 memory_order_relaxed); 427 size_t fail = 0; 428 while (fail < vol->extent_no) { 429 fibril_rwlock_read_lock(&vol->states_lock); 430 size_t best_e = get_ext(vol, ba, cnt, 431 rebuild_blk); 432 fibril_rwlock_read_unlock(&vol->states_lock); 433 if (best_e >= vol->extent_no) 434 break; 435 rc = hr_read_direct(vol->extents[best_e].svc_id, ba, 436 cnt, data_read); 437 if (rc != EOK) { 438 hr_raid1_ext_state_cb(vol, best_e, rc); 439 fail++; 440 } else { 441 successful++; 442 break; 443 } 444 } 445 446 #else 447 448 retry_split: 449 size_t good; 450 rebuild_blk = atomic_load_explicit(&vol->rebuild_blk, 451 memory_order_relaxed); 452 453 fibril_rwlock_read_lock(&vol->states_lock); 454 good = hr_raid1_count_good_r_extents(vol, ba, cnt, 455 rebuild_blk); 456 fibril_rwlock_read_unlock(&vol->states_lock); 457 458 size_t cnt_per_ext = (cnt + good - 1) / good; 459 if (cnt_per_ext * vol->bsize < HR_RAID1_READ_STRATEGY_SPLIT_THRESHOLD) 460 cnt_per_ext = cnt; 461 462 hr_fgroup_t *group = hr_fgroup_create(vol->fge, good); 463 464 fibril_rwlock_read_lock(&vol->states_lock); 465 size_t left = cnt; 466 size_t e = 0; 467 uint8_t *data = data_read; 468 size_t submitted = 0; 469 while (left > 0) { 470 if (e >= vol->extent_no) { 471 fibril_rwlock_read_unlock(&vol->states_lock); 472 if (submitted) 473 (void)hr_fgroup_wait(group, NULL, NULL); 474 goto retry_split; 475 } 476 477 hr_ext_state_t state = vol->extents[e].state; 478 if (state != HR_EXT_ONLINE && 479 (state != HR_EXT_REBUILD || 480 ba + cnt - 1 >= rebuild_blk)) { 481 e++; 482 continue; 483 } 484 485 hr_io_t *io = hr_fgroup_alloc(group); 486 io->extent = e; 487 io->data_read = data; 488 io->ba = ba + (cnt - left); 489 size_t cnt_to_dispatch = min(left, cnt_per_ext); 490 io->cnt = cnt_to_dispatch; 491 io->type = HR_BD_READ; 492 io->vol = vol; 493 494 hr_fgroup_submit(group, hr_io_worker, io); 495 submitted++; 496 497 data += cnt_to_dispatch * vol->bsize; 498 left -= cnt_to_dispatch; 499 e++; 500 } 501 502 fibril_rwlock_read_unlock(&vol->states_lock); 503 504 (void)hr_fgroup_wait(group, &successful, NULL); 505 #endif 506 507 return successful; 508 } 509 306 510 static errno_t hr_raid1_bd_op(hr_bd_op_type_t type, hr_volume_t *vol, 307 511 aoff64_t ba, size_t cnt, void *data_read, const void *data_write, … … 312 516 hr_range_lock_t *rl = NULL; 313 517 errno_t rc; 314 size_t i;315 518 uint64_t rebuild_blk; 316 519 … … 345 548 fibril_rwlock_read_lock(&vol->extents_lock); 346 549 347 size_t successful = 0; 550 size_t good; 551 size_t successful; 348 552 switch (type) { 349 553 case HR_BD_READ: 350 rebuild_blk = atomic_load_explicit(&vol->rebuild_blk, 351 memory_order_relaxed); 352 353 for (i = 0; i < vol->extent_no; i++) { 354 fibril_rwlock_read_lock(&vol->states_lock); 355 hr_ext_state_t state = vol->extents[i].state; 356 fibril_rwlock_read_unlock(&vol->states_lock); 357 358 if (state != HR_EXT_ONLINE && 359 (state != HR_EXT_REBUILD || 360 ba + cnt - 1 >= rebuild_blk)) { 361 continue; 362 } 363 364 rc = hr_read_direct(vol->extents[i].svc_id, ba, cnt, 365 data_read); 366 if (rc != EOK) { 367 hr_raid1_ext_state_cb(vol, i, rc); 368 } else { 369 successful++; 370 break; 371 } 372 } 554 successful = hr_raid1_read(vol, ba, cnt, data_read); 373 555 break; 374 556 case HR_BD_WRITE: … … 380 562 memory_order_relaxed); 381 563 382 size_t good = hr_raid1_count_good_extents(vol, ba, cnt,564 good = hr_raid1_count_good_w_extents(vol, ba, cnt, 383 565 rebuild_blk); 384 566 385 567 hr_fgroup_t *group = hr_fgroup_create(vol->fge, good); 386 568 387 for ( i = 0; i < vol->extent_no; i++) {569 for (size_t i = 0; i < vol->extent_no; i++) { 388 570 if (vol->extents[i].state != HR_EXT_ONLINE && 389 571 (vol->extents[i].state != HR_EXT_REBUILD || … … 402 584 io->extent = i; 403 585 io->data_write = data_write; 404 io->data_read = data_read;405 586 io->ba = ba; 406 587 io->cnt = cnt;
Note:
See TracChangeset
for help on using the changeset viewer.