aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2015-02-24 21:58:21 -0500
committerMike Snitzer <snitzer@redhat.com>2015-02-24 22:44:14 -0500
commitd379ecbac533d3ac45c7f155b1fc1b760abace6e (patch)
tree023c651a2ab45e6661faaddc0c345be6d2ebc835
parent489ab49e738667ba9d40b6d2b0b47910b5194208 (diff)
downloadlinux-dm-d379ecbac533d3ac45c7f155b1fc1b760abace6e.tar.gz
dm: don't start current request if it would've merged with the previous
Notice: this object is not reachable from any branch.
Request-based DM's dm_request_fn() is so fast to pull requests off the queue that steps need to be taken to promote merging by avoiding request processing if it makes sense. If the current request would've merged with previous request let the current request stay on the queue a bit longer. Suggested-by: Jens Axboe <axboe@fb.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Notice: this object is not reachable from any branch.
-rw-r--r--drivers/md/dm.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 52d995c511829..4c7a5597f7863 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -21,6 +21,7 @@
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/kthread.h>
+#include <linux/elevator.h> /* for rq_end_sector() */
#include <trace/events/block.h>
@@ -216,6 +217,10 @@ struct mapped_device {
struct kthread_worker kworker;
struct task_struct *kworker_task;
+
+ /* for request-based merge heuristic in dm_request_fn() */
+ sector_t last_rq_pos;
+ int last_rq_rw;
};
/*
@@ -1927,6 +1932,9 @@ static void dm_start_request(struct mapped_device *md, struct request *orig)
blk_start_request(orig);
atomic_inc(&md->pending[rq_data_dir(orig)]);
+ md->last_rq_pos = rq_end_sector(orig);
+ md->last_rq_rw = rq_data_dir(orig);
+
/*
* Hold the md reference here for the in-flight I/O.
* We can't rely on the reference count by device opener,
@@ -1979,6 +1987,10 @@ static void dm_request_fn(struct request_queue *q)
continue;
}
+ if (md_in_flight(md) && rq->bio && rq->bio->bi_vcnt == 1 &&
+ md->last_rq_pos == pos && md->last_rq_rw == rq_data_dir(rq))
+ goto out;
+
if (ti->type->busy && ti->type->busy(ti))
goto delay_and_out;