block: immediately dispatch big size request
authorShaohua Li <shli@fb.com>
Fri, 4 Nov 2016 00:03:53 +0000 (17:03 -0700)
committerJens Axboe <axboe@fb.com>
Fri, 4 Nov 2016 04:00:36 +0000 (22:00 -0600)
Currently block plug holds up to 16 non-mergeable requests. This makes
sense if the request size is small, eg, reduce lock contention. But if
request size is big enough, we don't need to worry about lock
contention. Holding such request makes no sense and it lows the disk
utilization.

In practice, this improves 10% throughput for my raid5 sequential write
workload.

The size (128k) is arbitrary right now, but it makes sure lock
contention is small. This probably could be more intelligent, eg, check
average request size holded. Since this is mainly for sequential IO,
probably not worthy.

V2: check the last request instead of the first request, so as long as
there is one big size request we flush the plug.

Signed-off-by: Shaohua Li <shli@fb.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
block/blk-core.c
include/linux/blkdev.h

index 0bfaa54d3e9f5d69c0a1817e042bacfa40895ef1..2deca48a4a0545380ce5f3f2d543236797754937 100644 (file)
@@ -1746,7 +1746,9 @@ get_rq:
                if (!request_count)
                        trace_block_plug(q);
                else {
-                       if (request_count >= BLK_MAX_REQUEST_COUNT) {
+                       struct request *last = list_entry_rq(plug->list.prev);
+                       if (request_count >= BLK_MAX_REQUEST_COUNT ||
+                           blk_rq_bytes(last) >= BLK_PLUG_FLUSH_SIZE) {
                                blk_flush_plug_list(plug, false);
                                trace_block_plug(q);
                        }
index 13d893a69b464d69136de6bd98ce188487b42719..9189a2d5c392a804a69c04be5d7303c3cb650541 100644 (file)
@@ -1173,6 +1173,7 @@ struct blk_plug {
        struct list_head cb_list; /* md requires an unplug callback */
 };
 #define BLK_MAX_REQUEST_COUNT 16
+#define BLK_PLUG_FLUSH_SIZE (128 * 1024)
 
 struct blk_plug_cb;
 typedef void (*blk_plug_cb_fn)(struct blk_plug_cb *, bool);