Commit fb1e7538 authored by Jens Axboe's avatar Jens Axboe

block: improve queue_should_plug() by looking at IO depths

Instead of just checking whether this device uses block layer
tagging, we can improve the detection by looking at the maximum
queue depth it has reached. If that crosses 4, then deem it a
queuing device.

This is important on high IOPS devices, since plugging hurts
the performance there (it can be as much as 10-15% of the sys
time).
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent 1f98a13f
...@@ -1146,7 +1146,7 @@ void init_request_from_bio(struct request *req, struct bio *bio) ...@@ -1146,7 +1146,7 @@ void init_request_from_bio(struct request *req, struct bio *bio)
*/ */
static inline bool queue_should_plug(struct request_queue *q) static inline bool queue_should_plug(struct request_queue *q)
{ {
return !(blk_queue_nonrot(q) && blk_queue_tagged(q)); return !(blk_queue_nonrot(q) && blk_queue_queuing(q));
} }
static int __make_request(struct request_queue *q, struct bio *bio) static int __make_request(struct request_queue *q, struct bio *bio)
...@@ -1857,8 +1857,15 @@ void blk_dequeue_request(struct request *rq) ...@@ -1857,8 +1857,15 @@ void blk_dequeue_request(struct request *rq)
* and to it is freed is accounted as io that is in progress at * and to it is freed is accounted as io that is in progress at
* the driver side. * the driver side.
*/ */
if (blk_account_rq(rq)) if (blk_account_rq(rq)) {
q->in_flight[rq_is_sync(rq)]++; q->in_flight[rq_is_sync(rq)]++;
/*
* Mark this device as supporting hardware queuing, if
* we have more IOs in flight than 4.
*/
if (!blk_queue_queuing(q) && queue_in_flight(q) > 4)
set_bit(QUEUE_FLAG_CQ, &q->queue_flags);
}
} }
/** /**
......
...@@ -459,6 +459,7 @@ struct request_queue ...@@ -459,6 +459,7 @@ struct request_queue
#define QUEUE_FLAG_NONROT 14 /* non-rotational device (SSD) */ #define QUEUE_FLAG_NONROT 14 /* non-rotational device (SSD) */
#define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ #define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */
#define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ #define QUEUE_FLAG_IO_STAT 15 /* do IO stats */
#define QUEUE_FLAG_CQ 16 /* hardware does queuing */
#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
(1 << QUEUE_FLAG_CLUSTER) | \ (1 << QUEUE_FLAG_CLUSTER) | \
...@@ -581,6 +582,7 @@ enum { ...@@ -581,6 +582,7 @@ enum {
#define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags) #define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
#define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags) #define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
#define blk_queue_queuing(q) test_bit(QUEUE_FLAG_CQ, &(q)->queue_flags)
#define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) #define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
#define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) #define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags)
#define blk_queue_nonrot(q) test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags) #define blk_queue_nonrot(q) test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment