Skip to content

Commit e0d245e

Browse files
committed
Merge branch 'md-next' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md into for-5.14/drivers
Pull MD changes from Song: "1) iostats rewrite by Guoqing Jiang; 2) raid5 lock contention optimization by Gal Ofri." * 'md-next' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md: md/raid5: avoid device_lock in read_one_chunk() md: add comments in md_integrity_register md: check level before create and exit io_acct_set md: Constify attribute_group structs md: mark some personalities as deprecated md/raid10: enable io accounting md/raid1: enable io accounting md/raid1: rename print_msg with r1bio_existed md/raid5: avoid redundant bio clone in raid5_read_one_chunk md/raid5: move checking badblock before clone bio in raid5_read_one_chunk md: add io accounting for raid0 and raid5 md: revert io stats accounting
2 parents 491e5b1 + 97ae272 commit e0d245e

File tree

13 files changed

+149
-83
lines changed

13 files changed

+149
-83
lines changed

drivers/md/Kconfig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ config MD_AUTODETECT
4747
If unsure, say Y.
4848

4949
config MD_LINEAR
50-
tristate "Linear (append) mode"
50+
tristate "Linear (append) mode (deprecated)"
5151
depends on BLK_DEV_MD
5252
help
5353
If you say Y here, then your multiple devices driver will be able to
@@ -158,7 +158,7 @@ config MD_RAID456
158158
If unsure, say Y.
159159

160160
config MD_MULTIPATH
161-
tristate "Multipath I/O support"
161+
tristate "Multipath I/O support (deprecated)"
162162
depends on BLK_DEV_MD
163163
help
164164
MD_MULTIPATH provides a simple multi-path personality for use
@@ -169,7 +169,7 @@ config MD_MULTIPATH
169169
If unsure, say N.
170170

171171
config MD_FAULTY
172-
tristate "Faulty test module for MD"
172+
tristate "Faulty test module for MD (deprecated)"
173173
depends on BLK_DEV_MD
174174
help
175175
The "faulty" module allows for a block device that occasionally returns

drivers/md/md-bitmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2616,7 +2616,7 @@ static struct attribute *md_bitmap_attrs[] = {
26162616
&max_backlog_used.attr,
26172617
NULL
26182618
};
2619-
struct attribute_group md_bitmap_group = {
2619+
const struct attribute_group md_bitmap_group = {
26202620
.name = "bitmap",
26212621
.attrs = md_bitmap_attrs,
26222622
};

drivers/md/md-faulty.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ static void raid_exit(void)
357357
module_init(raid_init);
358358
module_exit(raid_exit);
359359
MODULE_LICENSE("GPL");
360-
MODULE_DESCRIPTION("Fault injection personality for MD");
360+
MODULE_DESCRIPTION("Fault injection personality for MD (deprecated)");
361361
MODULE_ALIAS("md-personality-10"); /* faulty */
362362
MODULE_ALIAS("md-faulty");
363363
MODULE_ALIAS("md-level--5");

drivers/md/md-linear.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ static void linear_exit (void)
312312
module_init(linear_init);
313313
module_exit(linear_exit);
314314
MODULE_LICENSE("GPL");
315-
MODULE_DESCRIPTION("Linear device concatenation personality for MD");
315+
MODULE_DESCRIPTION("Linear device concatenation personality for MD (deprecated)");
316316
MODULE_ALIAS("md-personality-1"); /* LINEAR - deprecated*/
317317
MODULE_ALIAS("md-linear");
318318
MODULE_ALIAS("md-level--1");

drivers/md/md-multipath.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ static void __exit multipath_exit (void)
471471
module_init(multipath_init);
472472
module_exit(multipath_exit);
473473
MODULE_LICENSE("GPL");
474-
MODULE_DESCRIPTION("simple multi-path personality for MD");
474+
MODULE_DESCRIPTION("simple multi-path personality for MD (deprecated)");
475475
MODULE_ALIAS("md-personality-7"); /* MULTIPATH */
476476
MODULE_ALIAS("md-multipath");
477477
MODULE_ALIAS("md-level--4");

drivers/md/md.c

Lines changed: 65 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -441,30 +441,6 @@ void md_handle_request(struct mddev *mddev, struct bio *bio)
441441
}
442442
EXPORT_SYMBOL(md_handle_request);
443443

444-
struct md_io {
445-
struct mddev *mddev;
446-
bio_end_io_t *orig_bi_end_io;
447-
void *orig_bi_private;
448-
struct block_device *orig_bi_bdev;
449-
unsigned long start_time;
450-
};
451-
452-
static void md_end_io(struct bio *bio)
453-
{
454-
struct md_io *md_io = bio->bi_private;
455-
struct mddev *mddev = md_io->mddev;
456-
457-
bio_end_io_acct_remapped(bio, md_io->start_time, md_io->orig_bi_bdev);
458-
459-
bio->bi_end_io = md_io->orig_bi_end_io;
460-
bio->bi_private = md_io->orig_bi_private;
461-
462-
mempool_free(md_io, &mddev->md_io_pool);
463-
464-
if (bio->bi_end_io)
465-
bio->bi_end_io(bio);
466-
}
467-
468444
static blk_qc_t md_submit_bio(struct bio *bio)
469445
{
470446
const int rw = bio_data_dir(bio);
@@ -489,21 +465,6 @@ static blk_qc_t md_submit_bio(struct bio *bio)
489465
return BLK_QC_T_NONE;
490466
}
491467

492-
if (bio->bi_end_io != md_end_io) {
493-
struct md_io *md_io;
494-
495-
md_io = mempool_alloc(&mddev->md_io_pool, GFP_NOIO);
496-
md_io->mddev = mddev;
497-
md_io->orig_bi_end_io = bio->bi_end_io;
498-
md_io->orig_bi_private = bio->bi_private;
499-
md_io->orig_bi_bdev = bio->bi_bdev;
500-
501-
bio->bi_end_io = md_end_io;
502-
bio->bi_private = md_io;
503-
504-
md_io->start_time = bio_start_io_acct(bio);
505-
}
506-
507468
/* bio could be mergeable after passing to underlayer */
508469
bio->bi_opf &= ~REQ_NOMERGE;
509470

@@ -824,7 +785,7 @@ static struct mddev *mddev_alloc(dev_t unit)
824785
return ERR_PTR(error);
825786
}
826787

827-
static struct attribute_group md_redundancy_group;
788+
static const struct attribute_group md_redundancy_group;
828789

829790
void mddev_unlock(struct mddev *mddev)
830791
{
@@ -841,7 +802,7 @@ void mddev_unlock(struct mddev *mddev)
841802
* test it under the same mutex to ensure its correct value
842803
* is seen.
843804
*/
844-
struct attribute_group *to_remove = mddev->to_remove;
805+
const struct attribute_group *to_remove = mddev->to_remove;
845806
mddev->to_remove = NULL;
846807
mddev->sysfs_active = 1;
847808
mutex_unlock(&mddev->reconfig_mutex);
@@ -2379,7 +2340,15 @@ int md_integrity_register(struct mddev *mddev)
23792340
bdev_get_integrity(reference->bdev));
23802341

23812342
pr_debug("md: data integrity enabled on %s\n", mdname(mddev));
2382-
if (bioset_integrity_create(&mddev->bio_set, BIO_POOL_SIZE)) {
2343+
if (bioset_integrity_create(&mddev->bio_set, BIO_POOL_SIZE) ||
2344+
(mddev->level != 1 && mddev->level != 10 &&
2345+
bioset_integrity_create(&mddev->io_acct_set, BIO_POOL_SIZE))) {
2346+
/*
2347+
* No need to handle the failure of bioset_integrity_create,
2348+
* because the function is called by md_run() -> pers->run(),
2349+
* md_run calls bioset_exit -> bioset_integrity_free in case
2350+
* of failure case.
2351+
*/
23832352
pr_err("md: failed to create integrity pool for %s\n",
23842353
mdname(mddev));
23852354
return -EINVAL;
@@ -5538,7 +5507,7 @@ static struct attribute *md_redundancy_attrs[] = {
55385507
&md_degraded.attr,
55395508
NULL,
55405509
};
5541-
static struct attribute_group md_redundancy_group = {
5510+
static const struct attribute_group md_redundancy_group = {
55425511
.name = NULL,
55435512
.attrs = md_redundancy_attrs,
55445513
};
@@ -5608,7 +5577,8 @@ static void md_free(struct kobject *ko)
56085577

56095578
bioset_exit(&mddev->bio_set);
56105579
bioset_exit(&mddev->sync_set);
5611-
mempool_exit(&mddev->md_io_pool);
5580+
if (mddev->level != 1 && mddev->level != 10)
5581+
bioset_exit(&mddev->io_acct_set);
56125582
kfree(mddev);
56135583
}
56145584

@@ -5705,11 +5675,6 @@ static int md_alloc(dev_t dev, char *name)
57055675
*/
57065676
mddev->hold_active = UNTIL_STOP;
57075677

5708-
error = mempool_init_kmalloc_pool(&mddev->md_io_pool, BIO_POOL_SIZE,
5709-
sizeof(struct md_io));
5710-
if (error)
5711-
goto abort;
5712-
57135678
error = -ENOMEM;
57145679
mddev->queue = blk_alloc_queue(NUMA_NO_NODE);
57155680
if (!mddev->queue)
@@ -5907,7 +5872,14 @@ int md_run(struct mddev *mddev)
59075872
if (!bioset_initialized(&mddev->sync_set)) {
59085873
err = bioset_init(&mddev->sync_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS);
59095874
if (err)
5910-
return err;
5875+
goto exit_bio_set;
5876+
}
5877+
if (mddev->level != 1 && mddev->level != 10 &&
5878+
!bioset_initialized(&mddev->io_acct_set)) {
5879+
err = bioset_init(&mddev->io_acct_set, BIO_POOL_SIZE,
5880+
offsetof(struct md_io_acct, bio_clone), 0);
5881+
if (err)
5882+
goto exit_sync_set;
59115883
}
59125884

59135885
spin_lock(&pers_lock);
@@ -6035,6 +6007,7 @@ int md_run(struct mddev *mddev)
60356007
blk_queue_flag_set(QUEUE_FLAG_NONROT, mddev->queue);
60366008
else
60376009
blk_queue_flag_clear(QUEUE_FLAG_NONROT, mddev->queue);
6010+
blk_queue_flag_set(QUEUE_FLAG_IO_STAT, mddev->queue);
60386011
}
60396012
if (pers->sync_request) {
60406013
if (mddev->kobj.sd &&
@@ -6084,8 +6057,12 @@ int md_run(struct mddev *mddev)
60846057
module_put(pers->owner);
60856058
md_bitmap_destroy(mddev);
60866059
abort:
6087-
bioset_exit(&mddev->bio_set);
6060+
if (mddev->level != 1 && mddev->level != 10)
6061+
bioset_exit(&mddev->io_acct_set);
6062+
exit_sync_set:
60886063
bioset_exit(&mddev->sync_set);
6064+
exit_bio_set:
6065+
bioset_exit(&mddev->bio_set);
60896066
return err;
60906067
}
60916068
EXPORT_SYMBOL_GPL(md_run);
@@ -6309,6 +6286,8 @@ void md_stop(struct mddev *mddev)
63096286
__md_stop(mddev);
63106287
bioset_exit(&mddev->bio_set);
63116288
bioset_exit(&mddev->sync_set);
6289+
if (mddev->level != 1 && mddev->level != 10)
6290+
bioset_exit(&mddev->io_acct_set);
63126291
}
63136292

63146293
EXPORT_SYMBOL_GPL(md_stop);
@@ -8613,6 +8592,41 @@ void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev,
86138592
}
86148593
EXPORT_SYMBOL_GPL(md_submit_discard_bio);
86158594

8595+
static void md_end_io_acct(struct bio *bio)
8596+
{
8597+
struct md_io_acct *md_io_acct = bio->bi_private;
8598+
struct bio *orig_bio = md_io_acct->orig_bio;
8599+
8600+
orig_bio->bi_status = bio->bi_status;
8601+
8602+
bio_end_io_acct(orig_bio, md_io_acct->start_time);
8603+
bio_put(bio);
8604+
bio_endio(orig_bio);
8605+
}
8606+
8607+
/*
8608+
* Used by personalities that don't already clone the bio and thus can't
8609+
* easily add the timestamp to their extended bio structure.
8610+
*/
8611+
void md_account_bio(struct mddev *mddev, struct bio **bio)
8612+
{
8613+
struct md_io_acct *md_io_acct;
8614+
struct bio *clone;
8615+
8616+
if (!blk_queue_io_stat((*bio)->bi_bdev->bd_disk->queue))
8617+
return;
8618+
8619+
clone = bio_clone_fast(*bio, GFP_NOIO, &mddev->io_acct_set);
8620+
md_io_acct = container_of(clone, struct md_io_acct, bio_clone);
8621+
md_io_acct->orig_bio = *bio;
8622+
md_io_acct->start_time = bio_start_io_acct(*bio);
8623+
8624+
clone->bi_end_io = md_end_io_acct;
8625+
clone->bi_private = md_io_acct;
8626+
*bio = clone;
8627+
}
8628+
EXPORT_SYMBOL_GPL(md_account_bio);
8629+
86168630
/* md_allow_write(mddev)
86178631
* Calling this ensures that the array is marked 'active' so that writes
86188632
* may proceed without blocking. It is important to call this before

drivers/md/md.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -481,13 +481,13 @@ struct mddev {
481481
atomic_t max_corr_read_errors; /* max read retries */
482482
struct list_head all_mddevs;
483483

484-
struct attribute_group *to_remove;
484+
const struct attribute_group *to_remove;
485485

486486
struct bio_set bio_set;
487487
struct bio_set sync_set; /* for sync operations like
488488
* metadata and bitmap writes
489489
*/
490-
mempool_t md_io_pool;
490+
struct bio_set io_acct_set; /* for raid0 and raid5 io accounting */
491491

492492
/* Generic flush handling.
493493
* The last to finish preflush schedules a worker to submit
@@ -613,7 +613,7 @@ struct md_sysfs_entry {
613613
ssize_t (*show)(struct mddev *, char *);
614614
ssize_t (*store)(struct mddev *, const char *, size_t);
615615
};
616-
extern struct attribute_group md_bitmap_group;
616+
extern const struct attribute_group md_bitmap_group;
617617

618618
static inline struct kernfs_node *sysfs_get_dirent_safe(struct kernfs_node *sd, char *name)
619619
{
@@ -684,6 +684,12 @@ struct md_thread {
684684
void *private;
685685
};
686686

687+
struct md_io_acct {
688+
struct bio *orig_bio;
689+
unsigned long start_time;
690+
struct bio bio_clone;
691+
};
692+
687693
#define THREAD_WAKEUP 0
688694

689695
static inline void safe_put_page(struct page *p)
@@ -715,6 +721,7 @@ extern void md_error(struct mddev *mddev, struct md_rdev *rdev);
715721
extern void md_finish_reshape(struct mddev *mddev);
716722
void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev,
717723
struct bio *bio, sector_t start, sector_t size);
724+
void md_account_bio(struct mddev *mddev, struct bio **bio);
718725

719726
extern bool __must_check md_flush_request(struct mddev *mddev, struct bio *bio);
720727
extern void md_super_write(struct mddev *mddev, struct md_rdev *rdev,

drivers/md/raid0.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,9 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
546546
bio = split;
547547
}
548548

549+
if (bio->bi_pool != &mddev->bio_set)
550+
md_account_bio(mddev, &bio);
551+
549552
orig_sector = sector;
550553
zone = find_zone(mddev->private, &sector);
551554
switch (conf->layout) {

drivers/md/raid1.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ static void call_bio_endio(struct r1bio *r1_bio)
300300
if (!test_bit(R1BIO_Uptodate, &r1_bio->state))
301301
bio->bi_status = BLK_STS_IOERR;
302302

303+
if (blk_queue_io_stat(bio->bi_bdev->bd_disk->queue))
304+
bio_end_io_acct(bio, r1_bio->start_time);
303305
bio_endio(bio);
304306
}
305307

@@ -1210,7 +1212,7 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
12101212
const unsigned long do_sync = (bio->bi_opf & REQ_SYNC);
12111213
int max_sectors;
12121214
int rdisk;
1213-
bool print_msg = !!r1_bio;
1215+
bool r1bio_existed = !!r1_bio;
12141216
char b[BDEVNAME_SIZE];
12151217

12161218
/*
@@ -1220,7 +1222,7 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
12201222
*/
12211223
gfp_t gfp = r1_bio ? (GFP_NOIO | __GFP_HIGH) : GFP_NOIO;
12221224

1223-
if (print_msg) {
1225+
if (r1bio_existed) {
12241226
/* Need to get the block device name carefully */
12251227
struct md_rdev *rdev;
12261228
rcu_read_lock();
@@ -1252,7 +1254,7 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
12521254

12531255
if (rdisk < 0) {
12541256
/* couldn't find anywhere to read from */
1255-
if (print_msg) {
1257+
if (r1bio_existed) {
12561258
pr_crit_ratelimited("md/raid1:%s: %s: unrecoverable I/O read error for block %llu\n",
12571259
mdname(mddev),
12581260
b,
@@ -1263,7 +1265,7 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
12631265
}
12641266
mirror = conf->mirrors + rdisk;
12651267

1266-
if (print_msg)
1268+
if (r1bio_existed)
12671269
pr_info_ratelimited("md/raid1:%s: redirecting sector %llu to other mirror: %s\n",
12681270
mdname(mddev),
12691271
(unsigned long long)r1_bio->sector,
@@ -1292,6 +1294,9 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
12921294

12931295
r1_bio->read_disk = rdisk;
12941296

1297+
if (!r1bio_existed && blk_queue_io_stat(bio->bi_bdev->bd_disk->queue))
1298+
r1_bio->start_time = bio_start_io_acct(bio);
1299+
12951300
read_bio = bio_clone_fast(bio, gfp, &mddev->bio_set);
12961301

12971302
r1_bio->bios[rdisk] = read_bio;
@@ -1461,6 +1466,8 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
14611466
r1_bio->sectors = max_sectors;
14621467
}
14631468

1469+
if (blk_queue_io_stat(bio->bi_bdev->bd_disk->queue))
1470+
r1_bio->start_time = bio_start_io_acct(bio);
14641471
atomic_set(&r1_bio->remaining, 1);
14651472
atomic_set(&r1_bio->behind_remaining, 0);
14661473

drivers/md/raid1.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ struct r1bio {
158158
sector_t sector;
159159
int sectors;
160160
unsigned long state;
161+
unsigned long start_time;
161162
struct mddev *mddev;
162163
/*
163164
* original bio going to /dev/mdx

0 commit comments

Comments
 (0)