From 933262d614482e214c949ee13003d0a221acbd36 Mon Sep 17 00:00:00 2001 Message-Id: <933262d614482e214c949ee13003d0a221acbd36.1335442258.git.minovotn@redhat.com> In-Reply-To: <9655a7a810e4105c1af23cf484d228ebed7eab24.1335442258.git.minovotn@redhat.com> References: <9655a7a810e4105c1af23cf484d228ebed7eab24.1335442258.git.minovotn@redhat.com> From: Paolo Bonzini Date: Tue, 24 Apr 2012 16:17:32 +0200 Subject: [PATCH 2/2] Revert "raw-posix: do not linearize anymore direct I/O on Linux NFS" RH-Author: Paolo Bonzini Message-id: <1335284252-17072-1-git-send-email-pbonzini@redhat.com> Patchwork-id: 39435 O-Subject: [RHEL 6.3 qemu-kvm PATCH] Revert "raw-posix: do not linearize anymore direct I/O on Linux NFS" Bugzilla: 814617 RH-Acked-by: Asias He RH-Acked-by: Kevin Wolf RH-Acked-by: Markus Armbruster Bugzilla: 814617 Upstream status: Revert of revert of non-upstream patch Brew build: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=4334250 This reverts commit 9bf7a8d4e8e24c81eee0ce5d701f45d5042a3f88. QE found that performance is still not up to par. One problem is that the kernel expects page-aligned (not sector-aligned) buffers, but even fixing that in qemu_blockalign was not enough. Signed-off-by: Paolo Bonzini --- block/raw-posix.c | 59 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 8 deletions(-) Signed-off-by: Michal Novotny --- block/raw-posix.c | 59 +++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 51 insertions(+), 8 deletions(-) diff --git a/block/raw-posix.c b/block/raw-posix.c index f359187..477ced2 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -50,8 +50,10 @@ #endif #ifdef __linux__ #include +#include #include #include +#include #endif #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) #include @@ -125,6 +127,7 @@ typedef struct BDRVRawState { #endif uint8_t *aligned_buf; unsigned aligned_buf_size; + bool force_linearize; #ifdef CONFIG_XFS bool is_xfs : 1; #endif @@ -137,6 +140,38 @@ static int64_t raw_getlength(BlockDriverState *bs); static int cdrom_reopen(BlockDriverState *bs); #endif +#if defined(__linux__) +static bool is_vectored_io_slow(int fd, int bdrv_flags) +{ + struct statfs stfs; + int ret; + char *env_flag = getenv("QEMU_FORCE_LINEARIZE"); + + if (env_flag && strcasecmp(env_flag, "off") == 0) { + return false; + } + + do { + ret = fstatfs(fd, &stfs); + } while (ret != 0 && errno == EINTR); + + /* + * Linux NFS client splits vectored direct I/O requests into separate NFS + * requests so it is faster to submit a single buffer instead. + */ + if (!ret && stfs.f_type == NFS_SUPER_MAGIC && + (bdrv_flags & BDRV_O_NOCACHE)) { + return true; + } + return false; +} +#else /* !defined(__linux__) */ +static bool is_vectored_io_slow(int fd, int bdrv_flags) +{ + return false; +} +#endif + static int raw_open_common(BlockDriverState *bs, const char *filename, int bdrv_flags, int open_flags) { @@ -169,6 +204,7 @@ static int raw_open_common(BlockDriverState *bs, const char *filename, } s->fd = fd; s->aligned_buf = NULL; + s->force_linearize = is_vectored_io_slow(fd, bdrv_flags); if ((bdrv_flags & BDRV_O_NOCACHE)) { /* @@ -274,20 +310,27 @@ static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs, return NULL; /* + * Check if buffers need to be copied into a single linear buffer. + */ + if (s->force_linearize && qiov->niov > 1) { + type |= QEMU_AIO_MISALIGNED; + } + + /* * If O_DIRECT is used the buffer needs to be aligned on a sector * boundary. Check if this is the case or telll the low-level * driver that it needs to copy the buffer. */ - if (s->aligned_buf) { - if (!qiov_is_aligned(bs, qiov)) { - type |= QEMU_AIO_MISALIGNED; + if (s->aligned_buf && !qiov_is_aligned(bs, qiov)) { + type |= QEMU_AIO_MISALIGNED; + } + #ifdef CONFIG_LINUX_AIO - } else if (s->use_aio) { - return laio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov, - nb_sectors, cb, opaque, type); -#endif - } + if (s->use_aio && (type & QEMU_AIO_MISALIGNED) == 0) { + return laio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov, + nb_sectors, cb, opaque, type); } +#endif return paio_submit(bs, s->fd, sector_num, qiov, nb_sectors, cb, opaque, type); -- 1.7.7.6