* [PATCH 1/4] block: expose disk_map_sector_rcu() and hd_struct_put in genhd.h
2020-08-18 7:02 [PATCH 0/4] block: improve iostat for md/bcache partitions Song Liu
@ 2020-08-18 7:02 ` Song Liu
2020-08-18 19:45 ` Christoph Hellwig
2020-08-18 7:02 ` [PATCH 2/4] block: introduce part_[begin|end]_io_acct Song Liu
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Song Liu @ 2020-08-18 7:02 UTC (permalink / raw)
To: linux-block, linux-raid, linux-bcache
Cc: colyli, axboe, kernel-team, song, Song Liu
So they can be used in drivers.
Signed-off-by: Song Liu <songliubraving@fb.com>
---
block/blk.h | 8 --------
block/genhd.c | 1 +
include/linux/genhd.h | 8 ++++++++
3 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/block/blk.h b/block/blk.h
index 94f7c084f68fc..a6bc909480111 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -332,8 +332,6 @@ void blk_queue_free_zone_bitmaps(struct request_queue *q);
static inline void blk_queue_free_zone_bitmaps(struct request_queue *q) {}
#endif
-struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector);
-
int blk_alloc_devt(struct hd_struct *part, dev_t *devt);
void blk_free_devt(dev_t devt);
void blk_invalidate_devt(dev_t devt);
@@ -358,12 +356,6 @@ static inline int hd_struct_try_get(struct hd_struct *part)
return 1;
}
-static inline void hd_struct_put(struct hd_struct *part)
-{
- if (part->partno)
- percpu_ref_put(&part->ref);
-}
-
static inline void hd_free_part(struct hd_struct *part)
{
free_percpu(part->dkstats);
diff --git a/block/genhd.c b/block/genhd.c
index 60ae4e1b4d387..5b9333317dcb4 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -349,6 +349,7 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector)
rcu_read_unlock();
return part;
}
+EXPORT_SYMBOL_GPL(disk_map_sector_rcu);
/**
* disk_has_partitions
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 31a54072ffd65..b47c64f9f26b4 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -380,6 +380,14 @@ void bd_set_size(struct block_device *bdev, loff_t size);
int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long);
long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
+struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector);
+
+static inline void hd_struct_put(struct hd_struct *part)
+{
+ if (part->partno)
+ percpu_ref_put(&part->ref);
+}
+
#ifdef CONFIG_SYSFS
int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk);
void bd_unlink_disk_holder(struct block_device *bdev, struct gendisk *disk);
--
2.24.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/4] block: expose disk_map_sector_rcu() and hd_struct_put in genhd.h
2020-08-18 7:02 ` [PATCH 1/4] block: expose disk_map_sector_rcu() and hd_struct_put in genhd.h Song Liu
@ 2020-08-18 19:45 ` Christoph Hellwig
0 siblings, 0 replies; 8+ messages in thread
From: Christoph Hellwig @ 2020-08-18 19:45 UTC (permalink / raw)
To: Song Liu
Cc: linux-block, linux-raid, linux-bcache, colyli, axboe, kernel-team, song
On Tue, Aug 18, 2020 at 12:02:35AM -0700, Song Liu wrote:
> So they can be used in drivers.
Looking at your later patches I'd much rather hide the call to
disk_map_sector_rcu in the actual accounting helper.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/4] block: introduce part_[begin|end]_io_acct
2020-08-18 7:02 [PATCH 0/4] block: improve iostat for md/bcache partitions Song Liu
2020-08-18 7:02 ` [PATCH 1/4] block: expose disk_map_sector_rcu() and hd_struct_put in genhd.h Song Liu
@ 2020-08-18 7:02 ` Song Liu
2020-08-18 19:48 ` Christoph Hellwig
2020-08-18 7:02 ` [PATCH 3/4] md: use part_[begin|end]_io_acct instead of disk_[begin|end]_io_acct Song Liu
2020-08-18 7:02 ` [PATCH 4/4] bcache: " Song Liu
3 siblings, 1 reply; 8+ messages in thread
From: Song Liu @ 2020-08-18 7:02 UTC (permalink / raw)
To: linux-block, linux-raid, linux-bcache
Cc: colyli, axboe, kernel-team, song, Song Liu
These functions can be used to enable iostat for partitions on devices
like md, bcache.
Signed-off-by: Song Liu <songliubraving@fb.com>
---
block/blk-core.c | 20 ++++++++++++++++----
include/linux/blkdev.h | 5 +++++
2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/block/blk-core.c b/block/blk-core.c
index 93104c7470e8a..6603f56804f41 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1455,10 +1455,9 @@ void blk_account_io_start(struct request *rq)
part_stat_unlock();
}
-unsigned long disk_start_io_acct(struct gendisk *disk, unsigned int sectors,
+unsigned long part_start_io_acct(struct hd_struct *part, unsigned int sectors,
unsigned int op)
{
- struct hd_struct *part = &disk->part0;
const int sgrp = op_stat_group(op);
unsigned long now = READ_ONCE(jiffies);
@@ -1471,12 +1470,18 @@ unsigned long disk_start_io_acct(struct gendisk *disk, unsigned int sectors,
return now;
}
+EXPORT_SYMBOL(part_start_io_acct);
+
+unsigned long disk_start_io_acct(struct gendisk *disk, unsigned int sectors,
+ unsigned int op)
+{
+ return part_start_io_acct(&disk->part0, sectors, op);
+}
EXPORT_SYMBOL(disk_start_io_acct);
-void disk_end_io_acct(struct gendisk *disk, unsigned int op,
+void part_end_io_acct(struct hd_struct *part, unsigned int op,
unsigned long start_time)
{
- struct hd_struct *part = &disk->part0;
const int sgrp = op_stat_group(op);
unsigned long now = READ_ONCE(jiffies);
unsigned long duration = now - start_time;
@@ -1487,6 +1492,13 @@ void disk_end_io_acct(struct gendisk *disk, unsigned int op,
part_stat_local_dec(part, in_flight[op_is_write(op)]);
part_stat_unlock();
}
+EXPORT_SYMBOL(part_end_io_acct);
+
+void disk_end_io_acct(struct gendisk *disk, unsigned int op,
+ unsigned long start_time)
+{
+ part_end_io_acct(&disk->part0, op, start_time);
+}
EXPORT_SYMBOL(disk_end_io_acct);
/*
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 285b59cfc0646..894e55c91e1d8 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1931,6 +1931,11 @@ unsigned long disk_start_io_acct(struct gendisk *disk, unsigned int sectors,
void disk_end_io_acct(struct gendisk *disk, unsigned int op,
unsigned long start_time);
+unsigned long part_start_io_acct(struct hd_struct *part, unsigned int sectors,
+ unsigned int op);
+void part_end_io_acct(struct hd_struct *part, unsigned int op,
+ unsigned long start_time);
+
/**
* bio_start_io_acct - start I/O accounting for bio based drivers
* @bio: bio to start account for
--
2.24.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/4] block: introduce part_[begin|end]_io_acct
2020-08-18 7:02 ` [PATCH 2/4] block: introduce part_[begin|end]_io_acct Song Liu
@ 2020-08-18 19:48 ` Christoph Hellwig
0 siblings, 0 replies; 8+ messages in thread
From: Christoph Hellwig @ 2020-08-18 19:48 UTC (permalink / raw)
To: Song Liu
Cc: linux-block, linux-raid, linux-bcache, colyli, axboe, kernel-team, song
On Tue, Aug 18, 2020 at 12:02:36AM -0700, Song Liu wrote:
> These functions can be used to enable iostat for partitions on devices
> like md, bcache.
Please follow a model like bio_start_io_acct - that is pass a bio
for all the input parameters except for the gendisk. Given that we
don't have anywhere for the part to store that will need another
output paramater.
The end_io function should drop the hd_struct reference as well for
a well rounded API.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/4] md: use part_[begin|end]_io_acct instead of disk_[begin|end]_io_acct
2020-08-18 7:02 [PATCH 0/4] block: improve iostat for md/bcache partitions Song Liu
2020-08-18 7:02 ` [PATCH 1/4] block: expose disk_map_sector_rcu() and hd_struct_put in genhd.h Song Liu
2020-08-18 7:02 ` [PATCH 2/4] block: introduce part_[begin|end]_io_acct Song Liu
@ 2020-08-18 7:02 ` Song Liu
2020-08-18 7:02 ` [PATCH 4/4] bcache: " Song Liu
3 siblings, 0 replies; 8+ messages in thread
From: Song Liu @ 2020-08-18 7:02 UTC (permalink / raw)
To: linux-block, linux-raid, linux-bcache
Cc: colyli, axboe, kernel-team, song, Song Liu
This enables proper statistics in /proc/diskstats for md partitions.
Signed-off-by: Song Liu <songliubraving@fb.com>
---
drivers/md/md.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 6b511c9007d38..00ca65b206d13 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -470,6 +470,7 @@ struct md_io {
bio_end_io_t *orig_bi_end_io;
void *orig_bi_private;
unsigned long start_time;
+ struct hd_struct *part;
};
static void md_end_io(struct bio *bio)
@@ -477,7 +478,8 @@ static void md_end_io(struct bio *bio)
struct md_io *md_io = bio->bi_private;
struct mddev *mddev = md_io->mddev;
- disk_end_io_acct(mddev->gendisk, bio_op(bio), md_io->start_time);
+ part_end_io_acct(md_io->part, bio_op(bio), md_io->start_time);
+ hd_struct_put(md_io->part);
bio->bi_end_io = md_io->orig_bi_end_io;
bio->bi_private = md_io->orig_bi_private;
@@ -523,7 +525,9 @@ static blk_qc_t md_submit_bio(struct bio *bio)
bio->bi_end_io = md_end_io;
bio->bi_private = md_io;
- md_io->start_time = disk_start_io_acct(mddev->gendisk,
+ md_io->part = disk_map_sector_rcu(mddev->gendisk,
+ bio->bi_iter.bi_sector);
+ md_io->start_time = part_start_io_acct(md_io->part,
bio_sectors(bio),
bio_op(bio));
}
--
2.24.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/4] bcache: use part_[begin|end]_io_acct instead of disk_[begin|end]_io_acct
2020-08-18 7:02 [PATCH 0/4] block: improve iostat for md/bcache partitions Song Liu
` (2 preceding siblings ...)
2020-08-18 7:02 ` [PATCH 3/4] md: use part_[begin|end]_io_acct instead of disk_[begin|end]_io_acct Song Liu
@ 2020-08-18 7:02 ` Song Liu
2020-08-18 10:31 ` Coly Li
3 siblings, 1 reply; 8+ messages in thread
From: Song Liu @ 2020-08-18 7:02 UTC (permalink / raw)
To: linux-block, linux-raid, linux-bcache
Cc: colyli, axboe, kernel-team, song, Song Liu
This enables proper statistics in /proc/diskstats for bcache partitions.
Cc: Coly Li <colyli@suse.de>
Signed-off-by: Song Liu <songliubraving@fb.com>
---
drivers/md/bcache/request.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index 7de82c67597ce..1d946f601f7eb 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -475,6 +475,7 @@ struct search {
unsigned int read_dirty_data:1;
unsigned int cache_missed:1;
+ struct hd_struct *part;
unsigned long start_time;
struct btree_op op;
@@ -669,7 +670,8 @@ static void bio_complete(struct search *s)
{
if (s->orig_bio) {
/* Count on bcache device */
- disk_end_io_acct(s->d->disk, bio_op(s->orig_bio), s->start_time);
+ part_end_io_acct(s->part, bio_op(s->orig_bio), s->start_time);
+ hd_struct_put(s->part);
trace_bcache_request_end(s->d, s->orig_bio);
s->orig_bio->bi_status = s->iop.status;
@@ -731,7 +733,8 @@ static inline struct search *search_alloc(struct bio *bio,
s->write = op_is_write(bio_op(bio));
s->read_dirty_data = 0;
/* Count on the bcache device */
- s->start_time = disk_start_io_acct(d->disk, bio_sectors(bio), bio_op(bio));
+ s->part = disk_map_sector_rcu(d->disk, bio->bi_iter.bi_sector);
+ s->start_time = part_start_io_acct(s->part, bio_sectors(bio), bio_op(bio));
s->iop.c = d->c;
s->iop.bio = NULL;
s->iop.inode = d->id;
@@ -1072,6 +1075,7 @@ struct detached_dev_io_private {
unsigned long start_time;
bio_end_io_t *bi_end_io;
void *bi_private;
+ struct hd_struct *part;
};
static void detached_dev_end_io(struct bio *bio)
@@ -1083,7 +1087,8 @@ static void detached_dev_end_io(struct bio *bio)
bio->bi_private = ddip->bi_private;
/* Count on the bcache device */
- disk_end_io_acct(ddip->d->disk, bio_op(bio), ddip->start_time);
+ part_end_io_acct(ddip->part, bio_op(bio), ddip->start_time);
+ hd_struct_put(ddip->part);
if (bio->bi_status) {
struct cached_dev *dc = container_of(ddip->d,
@@ -1109,7 +1114,8 @@ static void detached_dev_do_request(struct bcache_device *d, struct bio *bio)
ddip = kzalloc(sizeof(struct detached_dev_io_private), GFP_NOIO);
ddip->d = d;
/* Count on the bcache device */
- ddip->start_time = disk_start_io_acct(d->disk, bio_sectors(bio), bio_op(bio));
+ ddip->part = disk_map_sector_rcu(d->disk, bio->bi_iter.bi_sector);
+ ddip->start_time = part_start_io_acct(ddip->part, bio_sectors(bio), bio_op(bio));
ddip->bi_end_io = bio->bi_end_io;
ddip->bi_private = bio->bi_private;
bio->bi_end_io = detached_dev_end_io;
--
2.24.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 4/4] bcache: use part_[begin|end]_io_acct instead of disk_[begin|end]_io_acct
2020-08-18 7:02 ` [PATCH 4/4] bcache: " Song Liu
@ 2020-08-18 10:31 ` Coly Li
0 siblings, 0 replies; 8+ messages in thread
From: Coly Li @ 2020-08-18 10:31 UTC (permalink / raw)
To: Song Liu; +Cc: linux-block, linux-raid, linux-bcache, axboe, kernel-team, song
On 2020/8/18 15:02, Song Liu wrote:
> This enables proper statistics in /proc/diskstats for bcache partitions.
>
> Cc: Coly Li <colyli@suse.de>
> Signed-off-by: Song Liu <songliubraving@fb.com>
The code looks good to me. It is fine to submit this bcache patch in
your submission path.
Reviewed-by: Coly Li <colyli@suse.de>
Thanks.
Coly Li
> ---
> drivers/md/bcache/request.c | 14 ++++++++++----
> 1 file changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
> index 7de82c67597ce..1d946f601f7eb 100644
> --- a/drivers/md/bcache/request.c
> +++ b/drivers/md/bcache/request.c
> @@ -475,6 +475,7 @@ struct search {
> unsigned int read_dirty_data:1;
> unsigned int cache_missed:1;
>
> + struct hd_struct *part;
> unsigned long start_time;
>
> struct btree_op op;
> @@ -669,7 +670,8 @@ static void bio_complete(struct search *s)
> {
> if (s->orig_bio) {
> /* Count on bcache device */
> - disk_end_io_acct(s->d->disk, bio_op(s->orig_bio), s->start_time);
> + part_end_io_acct(s->part, bio_op(s->orig_bio), s->start_time);
> + hd_struct_put(s->part);
>
> trace_bcache_request_end(s->d, s->orig_bio);
> s->orig_bio->bi_status = s->iop.status;
> @@ -731,7 +733,8 @@ static inline struct search *search_alloc(struct bio *bio,
> s->write = op_is_write(bio_op(bio));
> s->read_dirty_data = 0;
> /* Count on the bcache device */
> - s->start_time = disk_start_io_acct(d->disk, bio_sectors(bio), bio_op(bio));
> + s->part = disk_map_sector_rcu(d->disk, bio->bi_iter.bi_sector);
> + s->start_time = part_start_io_acct(s->part, bio_sectors(bio), bio_op(bio));
> s->iop.c = d->c;
> s->iop.bio = NULL;
> s->iop.inode = d->id;
> @@ -1072,6 +1075,7 @@ struct detached_dev_io_private {
> unsigned long start_time;
> bio_end_io_t *bi_end_io;
> void *bi_private;
> + struct hd_struct *part;
> };
>
> static void detached_dev_end_io(struct bio *bio)
> @@ -1083,7 +1087,8 @@ static void detached_dev_end_io(struct bio *bio)
> bio->bi_private = ddip->bi_private;
>
> /* Count on the bcache device */
> - disk_end_io_acct(ddip->d->disk, bio_op(bio), ddip->start_time);
> + part_end_io_acct(ddip->part, bio_op(bio), ddip->start_time);
> + hd_struct_put(ddip->part);
>
> if (bio->bi_status) {
> struct cached_dev *dc = container_of(ddip->d,
> @@ -1109,7 +1114,8 @@ static void detached_dev_do_request(struct bcache_device *d, struct bio *bio)
> ddip = kzalloc(sizeof(struct detached_dev_io_private), GFP_NOIO);
> ddip->d = d;
> /* Count on the bcache device */
> - ddip->start_time = disk_start_io_acct(d->disk, bio_sectors(bio), bio_op(bio));
> + ddip->part = disk_map_sector_rcu(d->disk, bio->bi_iter.bi_sector);
> + ddip->start_time = part_start_io_acct(ddip->part, bio_sectors(bio), bio_op(bio));
> ddip->bi_end_io = bio->bi_end_io;
> ddip->bi_private = bio->bi_private;
> bio->bi_end_io = detached_dev_end_io;
>
^ permalink raw reply [flat|nested] 8+ messages in thread