blk-mq: fix sysfs inflight counter
authorOmar Sandoval <osandov@fb.com>
Thu, 26 Apr 2018 07:21:59 +0000 (00:21 -0700)
committerJens Axboe <axboe@kernel.dk>
Thu, 26 Apr 2018 15:02:01 +0000 (09:02 -0600)
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>
block/blk-mq.c
block/blk-mq.h
block/genhd.c
block/partition-generic.c
include/linux/genhd.h

index 5450cbc61f8dfefaac10aac4054938656b3a48b7..9ce9cac16c3f5a7376f00b98e641e49d3e838592 100644 (file)
@@ -115,6 +115,25 @@ void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part,
        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;
index 89b5cd3a6c7088f3fac5d0dd14ef1fee76a49fc8..e1bb420dc5d6cdcea146d381e7d9f823b3d0b542 100644 (file)
@@ -188,7 +188,9 @@ static inline bool blk_mq_hw_queue_mapped(struct blk_mq_hw_ctx *hctx)
 }
 
 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)
 {
index dc7e089373b9444a0b83e176b196e2539e6ff59b..c4513fe1adda0761ac16db45d4f8bdfc30824504 100644 (file)
@@ -82,6 +82,18 @@ void part_in_flight(struct request_queue *q, struct hd_struct *part,
        }
 }
 
+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);
index 08dabcd8b6aefc6844bbb9d9e9c001e6ff71fb33..db57cced9b987371e6c8a3c72ff6721b9d540bda 100644 (file)
@@ -145,13 +145,15 @@ ssize_t part_stat_show(struct device *dev,
                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
index c826b0b5232aff63877bb441fb62e43128b4e976..6cb8a57896682af6dd29ac67b283d147f79e71a5 100644 (file)
@@ -368,7 +368,9 @@ static inline void free_part_stats(struct hd_struct *part)
        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,