Skip to content

Commit f40c153

Browse files
committed
Merge tag 'md-next-2023-04-28' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md into for-6.4/block
Pull MD fixes from Song: "1. Improve raid5 sequential IO performance on spinning disks, which fixes a regression since v6.0, by Jan Kara. 2. Fix bitmap offset types, which fixes an issue introduced in this merge window, by Jonathan Derrick." * tag 'md-next-2023-04-28' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md: md: Fix bitmap offset type in sb writer md/raid5: Improve performance for sequential IO
2 parents 952aa34 + b121197 commit f40c153

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

drivers/md/md-bitmap.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ static unsigned int optimal_io_size(struct block_device *bdev,
219219
}
220220

221221
static unsigned int bitmap_io_size(unsigned int io_size, unsigned int opt_size,
222-
sector_t start, sector_t boundary)
222+
loff_t start, loff_t boundary)
223223
{
224224
if (io_size != opt_size &&
225225
start + opt_size / SECTOR_SIZE <= boundary)
@@ -237,8 +237,8 @@ static int __write_sb_page(struct md_rdev *rdev, struct bitmap *bitmap,
237237
struct block_device *bdev;
238238
struct mddev *mddev = bitmap->mddev;
239239
struct bitmap_storage *store = &bitmap->storage;
240-
sector_t offset = mddev->bitmap_info.offset;
241-
sector_t ps, sboff, doff;
240+
loff_t sboff, offset = mddev->bitmap_info.offset;
241+
sector_t ps, doff;
242242
unsigned int size = PAGE_SIZE;
243243
unsigned int opt_size = PAGE_SIZE;
244244

drivers/md/raid5.c

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6079,6 +6079,38 @@ static enum stripe_result make_stripe_request(struct mddev *mddev,
60796079
return ret;
60806080
}
60816081

6082+
/*
6083+
* If the bio covers multiple data disks, find sector within the bio that has
6084+
* the lowest chunk offset in the first chunk.
6085+
*/
6086+
static sector_t raid5_bio_lowest_chunk_sector(struct r5conf *conf,
6087+
struct bio *bi)
6088+
{
6089+
int sectors_per_chunk = conf->chunk_sectors;
6090+
int raid_disks = conf->raid_disks;
6091+
int dd_idx;
6092+
struct stripe_head sh;
6093+
unsigned int chunk_offset;
6094+
sector_t r_sector = bi->bi_iter.bi_sector & ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
6095+
sector_t sector;
6096+
6097+
/* We pass in fake stripe_head to get back parity disk numbers */
6098+
sector = raid5_compute_sector(conf, r_sector, 0, &dd_idx, &sh);
6099+
chunk_offset = sector_div(sector, sectors_per_chunk);
6100+
if (sectors_per_chunk - chunk_offset >= bio_sectors(bi))
6101+
return r_sector;
6102+
/*
6103+
* Bio crosses to the next data disk. Check whether it's in the same
6104+
* chunk.
6105+
*/
6106+
dd_idx++;
6107+
while (dd_idx == sh.pd_idx || dd_idx == sh.qd_idx)
6108+
dd_idx++;
6109+
if (dd_idx >= raid_disks)
6110+
return r_sector;
6111+
return r_sector + sectors_per_chunk - chunk_offset;
6112+
}
6113+
60826114
static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
60836115
{
60846116
DEFINE_WAIT_FUNC(wait, woken_wake_function);
@@ -6150,6 +6182,17 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
61506182
}
61516183
md_account_bio(mddev, &bi);
61526184

6185+
/*
6186+
* Lets start with the stripe with the lowest chunk offset in the first
6187+
* chunk. That has the best chances of creating IOs adjacent to
6188+
* previous IOs in case of sequential IO and thus creates the most
6189+
* sequential IO pattern. We don't bother with the optimization when
6190+
* reshaping as the performance benefit is not worth the complexity.
6191+
*/
6192+
if (likely(conf->reshape_progress == MaxSector))
6193+
logical_sector = raid5_bio_lowest_chunk_sector(conf, bi);
6194+
s = (logical_sector - ctx.first_sector) >> RAID5_STRIPE_SHIFT(conf);
6195+
61536196
add_wait_queue(&conf->wait_for_overlap, &wait);
61546197
while (1) {
61556198
res = make_stripe_request(mddev, conf, &ctx, logical_sector,
@@ -6178,7 +6221,7 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
61786221
continue;
61796222
}
61806223

6181-
s = find_first_bit(ctx.sectors_to_do, stripe_cnt);
6224+
s = find_next_bit_wrap(ctx.sectors_to_do, stripe_cnt, s);
61826225
if (s == stripe_cnt)
61836226
break;
61846227

0 commit comments

Comments
 (0)