| From foo@baz Sun Jun 17 12:07:33 CEST 2018 |
| From: Omar Sandoval <osandov@fb.com> |
| Date: Thu, 26 Apr 2018 00:21:59 -0700 |
| Subject: blk-mq: fix sysfs inflight counter |
| |
| From: Omar Sandoval <osandov@fb.com> |
| |
| [ Upstream commit bf0ddaba65ddbb2715af97041da8e7a45b2d8628 ] |
| |
| When the blk-mq inflight implementation was added, /proc/diskstats was |
| converted to use it, but /sys/block/$dev/inflight was not. Fix it by |
| adding another helper to count in-flight requests by data direction. |
| |
| Fixes: f299b7c7a9de ("blk-mq: provide internal in-flight variant") |
| Signed-off-by: Omar Sandoval <osandov@fb.com> |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| block/blk-mq.c | 19 +++++++++++++++++++ |
| block/blk-mq.h | 4 +++- |
| block/genhd.c | 12 ++++++++++++ |
| block/partition-generic.c | 10 ++++++---- |
| include/linux/genhd.h | 4 +++- |
| 5 files changed, 43 insertions(+), 6 deletions(-) |
| |
| --- a/block/blk-mq.c |
| +++ b/block/blk-mq.c |
| @@ -118,6 +118,25 @@ void blk_mq_in_flight(struct request_que |
| blk_mq_queue_tag_busy_iter(q, blk_mq_check_inflight, &mi); |
| } |
| |
| +static void blk_mq_check_inflight_rw(struct blk_mq_hw_ctx *hctx, |
| + struct request *rq, void *priv, |
| + bool reserved) |
| +{ |
| + struct mq_inflight *mi = priv; |
| + |
| + if (rq->part == mi->part) |
| + mi->inflight[rq_data_dir(rq)]++; |
| +} |
| + |
| +void blk_mq_in_flight_rw(struct request_queue *q, struct hd_struct *part, |
| + unsigned int inflight[2]) |
| +{ |
| + struct mq_inflight mi = { .part = part, .inflight = inflight, }; |
| + |
| + inflight[0] = inflight[1] = 0; |
| + blk_mq_queue_tag_busy_iter(q, blk_mq_check_inflight_rw, &mi); |
| +} |
| + |
| void blk_freeze_queue_start(struct request_queue *q) |
| { |
| int freeze_depth; |
| --- a/block/blk-mq.h |
| +++ b/block/blk-mq.h |
| @@ -185,7 +185,9 @@ static inline bool blk_mq_hw_queue_mappe |
| } |
| |
| void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part, |
| - unsigned int inflight[2]); |
| + unsigned int inflight[2]); |
| +void blk_mq_in_flight_rw(struct request_queue *q, struct hd_struct *part, |
| + unsigned int inflight[2]); |
| |
| static inline void blk_mq_put_dispatch_budget(struct blk_mq_hw_ctx *hctx) |
| { |
| --- a/block/genhd.c |
| +++ b/block/genhd.c |
| @@ -82,6 +82,18 @@ void part_in_flight(struct request_queue |
| } |
| } |
| |
| +void part_in_flight_rw(struct request_queue *q, struct hd_struct *part, |
| + unsigned int inflight[2]) |
| +{ |
| + if (q->mq_ops) { |
| + blk_mq_in_flight_rw(q, part, inflight); |
| + return; |
| + } |
| + |
| + inflight[0] = atomic_read(&part->in_flight[0]); |
| + inflight[1] = atomic_read(&part->in_flight[1]); |
| +} |
| + |
| struct hd_struct *__disk_get_part(struct gendisk *disk, int partno) |
| { |
| struct disk_part_tbl *ptbl = rcu_dereference(disk->part_tbl); |
| --- a/block/partition-generic.c |
| +++ b/block/partition-generic.c |
| @@ -145,13 +145,15 @@ ssize_t part_stat_show(struct device *de |
| jiffies_to_msecs(part_stat_read(p, time_in_queue))); |
| } |
| |
| -ssize_t part_inflight_show(struct device *dev, |
| - struct device_attribute *attr, char *buf) |
| +ssize_t part_inflight_show(struct device *dev, struct device_attribute *attr, |
| + char *buf) |
| { |
| struct hd_struct *p = dev_to_part(dev); |
| + struct request_queue *q = part_to_disk(p)->queue; |
| + unsigned int inflight[2]; |
| |
| - return sprintf(buf, "%8u %8u\n", atomic_read(&p->in_flight[0]), |
| - atomic_read(&p->in_flight[1])); |
| + part_in_flight_rw(q, p, inflight); |
| + return sprintf(buf, "%8u %8u\n", inflight[0], inflight[1]); |
| } |
| |
| #ifdef CONFIG_FAIL_MAKE_REQUEST |
| --- a/include/linux/genhd.h |
| +++ b/include/linux/genhd.h |
| @@ -368,7 +368,9 @@ static inline void free_part_stats(struc |
| part_stat_add(cpu, gendiskp, field, -subnd) |
| |
| void part_in_flight(struct request_queue *q, struct hd_struct *part, |
| - unsigned int inflight[2]); |
| + unsigned int inflight[2]); |
| +void part_in_flight_rw(struct request_queue *q, struct hd_struct *part, |
| + unsigned int inflight[2]); |
| void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, |
| int rw); |
| void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, |