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 <andreas.dilger@intel.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Isaac Huang <he.huang@intel.com>
Closes #5181
This commit is contained in:
Isaac Huang 2016-09-29 14:13:31 -06:00 committed by Brian Behlendorf
parent 8a1cf1a560
commit e8ac4557af
3 changed files with 35 additions and 0 deletions

View File

@ -21,3 +21,24 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BIO_RW_UNPLUG], [
]) ])
EXTRA_KCFLAGS="$tmp_flags" 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"
])

View File

@ -34,6 +34,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS
ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS
ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BIO_RW_UNPLUG 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_DISK_RO
ZFS_AC_KERNEL_GET_GENDISK ZFS_AC_KERNEL_GET_GENDISK
ZFS_AC_KERNEL_DISCARD_GRANULARITY ZFS_AC_KERNEL_DISCARD_GRANULARITY

View File

@ -524,6 +524,9 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio, caddr_t kbuf_ptr,
uint64_t bio_offset; uint64_t bio_offset;
int bio_size, bio_count = 16; int bio_size, bio_count = 16;
int i = 0, error = 0; 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); 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 */ /* Extra reference to protect dio_request during vdev_submit_bio */
vdev_disk_dio_get(dr); 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 */ /* Submit all bio's associated with this dio */
for (i = 0; i < dr->dr_bio_count; i++) for (i = 0; i < dr->dr_bio_count; i++)
if (dr->dr_bio[i]) if (dr->dr_bio[i])
vdev_submit_bio(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); (void) vdev_disk_dio_put(dr);
return (error); return (error);