summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIsaac Huang <[email protected]>2016-09-29 14:13:31 -0600
committerBrian Behlendorf <[email protected]>2016-09-29 13:13:31 -0700
commite8ac4557af67a46a2cb90bd7db4d426c0b358d51 (patch)
tree4ce1e63abedea5fc71d3dde6415cebbdf806f080
parent8a1cf1a5608151635b67d89613e51427b177dab0 (diff)
Explicit block device plugging when submitting multiple BIOs
Without plugging, the default 'noop' scheduler will not merge the BIOs which are part of a large ZIO. Reviewed-by: Andreas Dilger <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Isaac Huang <[email protected]> Closes #5181
-rw-r--r--config/kernel-blk-queue-unplug.m421
-rw-r--r--config/kernel.m41
-rw-r--r--module/zfs/vdev_disk.c13
3 files changed, 35 insertions, 0 deletions
diff --git a/config/kernel-blk-queue-unplug.m4 b/config/kernel-blk-queue-unplug.m4
index 45cc2322a..075fbccd1 100644
--- a/config/kernel-blk-queue-unplug.m4
+++ b/config/kernel-blk-queue-unplug.m4
@@ -21,3 +21,24 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BIO_RW_UNPLUG], [
])
EXTRA_KCFLAGS="$tmp_flags"
])
+
+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BLK_PLUG], [
+ AC_MSG_CHECKING([whether struct blk_plug is available])
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/blkdev.h>
+ ],[
+ struct blk_plug plug;
+
+ blk_start_plug(&plug);
+ blk_finish_plug(&plug);
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_HAVE_BLK_PLUG, 1,
+ [struct blk_plug is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ EXTRA_KCFLAGS="$tmp_flags"
+])
diff --git a/config/kernel.m4 b/config/kernel.m4
index 798f3511b..c53e61157 100644
--- a/config/kernel.m4
+++ b/config/kernel.m4
@@ -34,6 +34,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS
ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS
ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BIO_RW_UNPLUG
+ ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BLK_PLUG
ZFS_AC_KERNEL_GET_DISK_RO
ZFS_AC_KERNEL_GET_GENDISK
ZFS_AC_KERNEL_DISCARD_GRANULARITY
diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c
index e399e6630..ce65760ee 100644
--- a/module/zfs/vdev_disk.c
+++ b/module/zfs/vdev_disk.c
@@ -524,6 +524,9 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio, caddr_t kbuf_ptr,
uint64_t bio_offset;
int bio_size, bio_count = 16;
int i = 0, error = 0;
+#if defined(HAVE_BLK_QUEUE_HAVE_BLK_PLUG)
+ struct blk_plug plug;
+#endif
ASSERT3U(kbuf_offset + kbuf_size, <=, bdev->bd_inode->i_size);
@@ -592,11 +595,21 @@ retry:
/* Extra reference to protect dio_request during vdev_submit_bio */
vdev_disk_dio_get(dr);
+#if defined(HAVE_BLK_QUEUE_HAVE_BLK_PLUG)
+ if (dr->dr_bio_count > 1)
+ blk_start_plug(&plug);
+#endif
+
/* Submit all bio's associated with this dio */
for (i = 0; i < dr->dr_bio_count; i++)
if (dr->dr_bio[i])
vdev_submit_bio(dr->dr_bio[i]);
+#if defined(HAVE_BLK_QUEUE_HAVE_BLK_PLUG)
+ if (dr->dr_bio_count > 1)
+ blk_finish_plug(&plug);
+#endif
+
(void) vdev_disk_dio_put(dr);
return (error);