[dm-devel] [patch 5/5] block: use a driver-specific handler for the "inflight" value
Mikulas Patocka
mpatocka at redhat.com
Tue Nov 6 21:35:03 UTC 2018
Device mapper was converted to percpu inflight counters. In order to
display the correct values in the "inflight" sysfs file, we need a custom
callback that sums the percpu counters.
Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
---
block/blk-settings.c | 6 ++++++
block/genhd.c | 5 +++++
drivers/md/dm.c | 18 ++++++++++++++++++
include/linux/blkdev.h | 4 ++++
4 files changed, 33 insertions(+)
Index: linux-2.6/block/genhd.c
===================================================================
--- linux-2.6.orig/block/genhd.c 2018-11-06 22:31:46.350000000 +0100
+++ linux-2.6/block/genhd.c 2018-11-06 22:31:46.350000000 +0100
@@ -85,6 +85,11 @@ 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->get_inflight_fn) {
+ q->get_inflight_fn(q, inflight);
+ return;
+ }
+
if (q->mq_ops) {
blk_mq_in_flight_rw(q, part, inflight);
return;
Index: linux-2.6/include/linux/blkdev.h
===================================================================
--- linux-2.6.orig/include/linux/blkdev.h 2018-11-06 22:31:46.350000000 +0100
+++ linux-2.6/include/linux/blkdev.h 2018-11-06 22:31:46.350000000 +0100
@@ -324,6 +324,7 @@ typedef int (lld_busy_fn) (struct reques
typedef int (bsg_job_fn) (struct bsg_job *);
typedef int (init_rq_fn)(struct request_queue *, struct request *, gfp_t);
typedef void (exit_rq_fn)(struct request_queue *, struct request *);
+typedef void (get_inflight_fn)(struct request_queue *, unsigned int [2]);
enum blk_eh_timer_return {
BLK_EH_DONE, /* drivers has completed the command */
@@ -466,6 +467,8 @@ struct request_queue {
exit_rq_fn *exit_rq_fn;
/* Called from inside blk_get_request() */
void (*initialize_rq_fn)(struct request *rq);
+ /* Called to get the "inflight" values */
+ get_inflight_fn *get_inflight_fn;
const struct blk_mq_ops *mq_ops;
@@ -1232,6 +1235,7 @@ extern int blk_queue_dma_drain(struct re
dma_drain_needed_fn *dma_drain_needed,
void *buf, unsigned int size);
extern void blk_queue_lld_busy(struct request_queue *q, lld_busy_fn *fn);
+extern void blk_queue_get_inflight(struct request_queue *q, get_inflight_fn *fn);
extern void blk_queue_segment_boundary(struct request_queue *, unsigned long);
extern void blk_queue_virt_boundary(struct request_queue *, unsigned long);
extern void blk_queue_prep_rq(struct request_queue *, prep_rq_fn *pfn);
Index: linux-2.6/block/blk-settings.c
===================================================================
--- linux-2.6.orig/block/blk-settings.c 2018-11-06 22:31:46.350000000 +0100
+++ linux-2.6/block/blk-settings.c 2018-11-06 22:31:46.350000000 +0100
@@ -79,6 +79,12 @@ void blk_queue_lld_busy(struct request_q
}
EXPORT_SYMBOL_GPL(blk_queue_lld_busy);
+void blk_queue_get_inflight(struct request_queue *q, get_inflight_fn *fn)
+{
+ q->get_inflight_fn = fn;
+}
+EXPORT_SYMBOL_GPL(blk_queue_get_inflight);
+
/**
* blk_set_default_limits - reset limits to default values
* @lim: the queue_limits structure to reset
Index: linux-2.6/drivers/md/dm.c
===================================================================
--- linux-2.6.orig/drivers/md/dm.c 2018-11-06 22:31:46.350000000 +0100
+++ linux-2.6/drivers/md/dm.c 2018-11-06 22:31:46.350000000 +0100
@@ -662,6 +662,23 @@ static void end_io_acct(struct dm_io *io
}
}
+static void dm_get_inflight(struct request_queue *q, unsigned int inflight[2])
+{
+ struct mapped_device *md = q->queuedata;
+ int cpu;
+
+ inflight[READ] = inflight[WRITE] = 0;
+ for_each_possible_cpu(cpu) {
+ struct dm_percpu *p = per_cpu_ptr(md->counters, cpu);
+ inflight[READ] += p->inflight[READ];
+ inflight[WRITE] += p->inflight[WRITE];
+ }
+ if ((int)inflight[READ] < 0)
+ inflight[READ] = 0;
+ if ((int)inflight[WRITE] < 0)
+ inflight[WRITE] = 0;
+}
+
/*
* Add the bio to the list of deferred io.
*/
@@ -2242,6 +2259,7 @@ int dm_setup_md_queue(struct mapped_devi
case DM_TYPE_NVME_BIO_BASED:
dm_init_normal_md_queue(md);
blk_queue_make_request(md->queue, dm_make_request);
+ blk_queue_get_inflight(md->queue, dm_get_inflight);
break;
case DM_TYPE_NONE:
WARN_ON_ONCE(true);
More information about the dm-devel
mailing list