Skip to content

Commit eb051b2

Browse files
committed
Merge tag 'md-next-20230817' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md into for-6.6/block
Pull MD changes from Song: "1. Fix perf regression for raid0 large sequential writes, by Jan Kara. 2. Fix split bio iostat for raid0, by David Jeffery. 3. Various raid1 fixes, by Heinz Mauelshagen and Xueshi Hu." * tag 'md-next-20230817' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md: md: raid0: account for split bio in iostat accounting md/raid0: Fix performance regression for large sequential writes md/raid0: Factor out helper for mapping and submitting a bio md raid1: allow writebehind to work on any leg device set WriteMostly md/raid1: hold the barrier until handle_read_error() finishes md/raid1: free the r1bio before waiting for blocked rdev md/raid1: call free_r1bio() before allow_barrier() in raid_end_bio_io()
2 parents ec14a87 + cc22b54 commit eb051b2

File tree

2 files changed

+51
-49
lines changed

2 files changed

+51
-49
lines changed

drivers/md/raid0.c

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -545,68 +545,34 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio)
545545
bio_endio(bio);
546546
}
547547

548-
static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
548+
static void raid0_map_submit_bio(struct mddev *mddev, struct bio *bio)
549549
{
550550
struct r0conf *conf = mddev->private;
551551
struct strip_zone *zone;
552552
struct md_rdev *tmp_dev;
553-
sector_t bio_sector;
554-
sector_t sector;
555-
sector_t orig_sector;
556-
unsigned chunk_sects;
557-
unsigned sectors;
558-
559-
if (unlikely(bio->bi_opf & REQ_PREFLUSH)
560-
&& md_flush_request(mddev, bio))
561-
return true;
553+
sector_t bio_sector = bio->bi_iter.bi_sector;
554+
sector_t sector = bio_sector;
562555

563-
if (unlikely((bio_op(bio) == REQ_OP_DISCARD))) {
564-
raid0_handle_discard(mddev, bio);
565-
return true;
566-
}
556+
md_account_bio(mddev, &bio);
567557

568-
bio_sector = bio->bi_iter.bi_sector;
569-
sector = bio_sector;
570-
chunk_sects = mddev->chunk_sectors;
571-
572-
sectors = chunk_sects -
573-
(likely(is_power_of_2(chunk_sects))
574-
? (sector & (chunk_sects-1))
575-
: sector_div(sector, chunk_sects));
576-
577-
/* Restore due to sector_div */
578-
sector = bio_sector;
579-
580-
if (sectors < bio_sectors(bio)) {
581-
struct bio *split = bio_split(bio, sectors, GFP_NOIO,
582-
&mddev->bio_set);
583-
bio_chain(split, bio);
584-
submit_bio_noacct(bio);
585-
bio = split;
586-
}
587-
588-
if (bio->bi_pool != &mddev->bio_set)
589-
md_account_bio(mddev, &bio);
590-
591-
orig_sector = sector;
592558
zone = find_zone(mddev->private, &sector);
593559
switch (conf->layout) {
594560
case RAID0_ORIG_LAYOUT:
595-
tmp_dev = map_sector(mddev, zone, orig_sector, &sector);
561+
tmp_dev = map_sector(mddev, zone, bio_sector, &sector);
596562
break;
597563
case RAID0_ALT_MULTIZONE_LAYOUT:
598564
tmp_dev = map_sector(mddev, zone, sector, &sector);
599565
break;
600566
default:
601567
WARN(1, "md/raid0:%s: Invalid layout\n", mdname(mddev));
602568
bio_io_error(bio);
603-
return true;
569+
return;
604570
}
605571

606572
if (unlikely(is_rdev_broken(tmp_dev))) {
607573
bio_io_error(bio);
608574
md_error(mddev, tmp_dev);
609-
return true;
575+
return;
610576
}
611577

612578
bio_set_dev(bio, tmp_dev->bdev);
@@ -618,6 +584,40 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
618584
bio_sector);
619585
mddev_check_write_zeroes(mddev, bio);
620586
submit_bio_noacct(bio);
587+
}
588+
589+
static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
590+
{
591+
sector_t sector;
592+
unsigned chunk_sects;
593+
unsigned sectors;
594+
595+
if (unlikely(bio->bi_opf & REQ_PREFLUSH)
596+
&& md_flush_request(mddev, bio))
597+
return true;
598+
599+
if (unlikely((bio_op(bio) == REQ_OP_DISCARD))) {
600+
raid0_handle_discard(mddev, bio);
601+
return true;
602+
}
603+
604+
sector = bio->bi_iter.bi_sector;
605+
chunk_sects = mddev->chunk_sectors;
606+
607+
sectors = chunk_sects -
608+
(likely(is_power_of_2(chunk_sects))
609+
? (sector & (chunk_sects-1))
610+
: sector_div(sector, chunk_sects));
611+
612+
if (sectors < bio_sectors(bio)) {
613+
struct bio *split = bio_split(bio, sectors, GFP_NOIO,
614+
&mddev->bio_set);
615+
bio_chain(split, bio);
616+
raid0_map_submit_bio(mddev, bio);
617+
bio = split;
618+
}
619+
620+
raid0_map_submit_bio(mddev, bio);
621621
return true;
622622
}
623623

drivers/md/raid1.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ static void raid_end_bio_io(struct r1bio *r1_bio)
311311
{
312312
struct bio *bio = r1_bio->master_bio;
313313
struct r1conf *conf = r1_bio->mddev->private;
314+
sector_t sector = r1_bio->sector;
314315

315316
/* if nobody has done the final endio yet, do it now */
316317
if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
@@ -321,13 +322,13 @@ static void raid_end_bio_io(struct r1bio *r1_bio)
321322

322323
call_bio_endio(r1_bio);
323324
}
325+
326+
free_r1bio(r1_bio);
324327
/*
325328
* Wake up any possible resync thread that waits for the device
326329
* to go idle. All I/Os, even write-behind writes, are done.
327330
*/
328-
allow_barrier(conf, r1_bio->sector);
329-
330-
free_r1bio(r1_bio);
331+
allow_barrier(conf, sector);
331332
}
332333

333334
/*
@@ -1377,6 +1378,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
13771378
return;
13781379
}
13791380

1381+
retry_write:
13801382
r1_bio = alloc_r1bio(mddev, bio);
13811383
r1_bio->sectors = max_write_sectors;
13821384

@@ -1392,7 +1394,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
13921394
*/
13931395

13941396
disks = conf->raid_disks * 2;
1395-
retry_write:
13961397
blocked_rdev = NULL;
13971398
rcu_read_lock();
13981399
max_sectors = r1_bio->sectors;
@@ -1472,7 +1473,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
14721473
for (j = 0; j < i; j++)
14731474
if (r1_bio->bios[j])
14741475
rdev_dec_pending(conf->mirrors[j].rdev, mddev);
1475-
r1_bio->state = 0;
1476+
free_r1bio(r1_bio);
14761477
allow_barrier(conf, bio->bi_iter.bi_sector);
14771478

14781479
if (bio->bi_opf & REQ_NOWAIT) {
@@ -1522,8 +1523,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
15221523
* Not if there are too many, or cannot
15231524
* allocate memory, or a reader on WriteMostly
15241525
* is waiting for behind writes to flush */
1525-
if (bitmap &&
1526-
test_bit(WriteMostly, &rdev->flags) &&
1526+
if (bitmap && write_behind &&
15271527
(atomic_read(&bitmap->behind_writes)
15281528
< mddev->bitmap_info.max_write_behind) &&
15291529
!waitqueue_active(&bitmap->behind_wait)) {
@@ -2510,6 +2510,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
25102510
struct mddev *mddev = conf->mddev;
25112511
struct bio *bio;
25122512
struct md_rdev *rdev;
2513+
sector_t sector;
25132514

25142515
clear_bit(R1BIO_ReadError, &r1_bio->state);
25152516
/* we got a read error. Maybe the drive is bad. Maybe just
@@ -2539,12 +2540,13 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
25392540
}
25402541

25412542
rdev_dec_pending(rdev, conf->mddev);
2542-
allow_barrier(conf, r1_bio->sector);
2543+
sector = r1_bio->sector;
25432544
bio = r1_bio->master_bio;
25442545

25452546
/* Reuse the old r1_bio so that the IO_BLOCKED settings are preserved */
25462547
r1_bio->state = 0;
25472548
raid1_read_request(mddev, bio, r1_bio->sectors, r1_bio);
2549+
allow_barrier(conf, sector);
25482550
}
25492551

25502552
static void raid1d(struct md_thread *thread)

0 commit comments

Comments
 (0)