qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 6/6] experimental native preadv/pwritev support for Linux
Date: Mon, 16 Mar 2009 12:38:24 +0100	[thread overview]
Message-ID: <49BE3A30.6060205@redhat.com> (raw)
In-Reply-To: <20090314193127.GC3799@lst.de>

[-- Attachment #1: Type: text/plain, Size: 822 bytes --]

Christoph Hellwig wrote:
> 
> This ties up Gerd Hoffmann's unmegred preadv/pwritev syscalls to qemu.  Use with
> care as the syscall numbers aren't finalized yet.
> 
> If someone of the BSD folks is interested it should be trivial to tie this up
> for the preadv/pwritev syscalls that have been around there for a while.
> 
> Probably wants some optimization to not try preadv/pwritev again once we got
> the first ENOSYS.

See $patch I've hacked up a while ago.  I think it already ran over the
list a while ago, /me was waiting for the preadv kernel patches hitting
mainline before trying to re-submit with the final syscall numbers and
the warning removed.

It provides qemu_p{read,write}v() functions.  Adds autoconf check for
*BSD, does linux syscall windup, runtime check and emulation for old
kernels.

HTH,
  Gerd

[-- Attachment #2: 0001-preadv-writev-code-for-qemu.patch --]
[-- Type: text/plain, Size: 6176 bytes --]

>From 5ab001859f3abeb792ef22d073d2bc38f6bb8604 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Thu, 22 Jan 2009 16:22:41 +0100
Subject: [PATCH] preadv/writev code for qemu.

---
 Makefile           |    1 +
 configure          |   14 +++++
 qemu-common.h      |    3 +
 qemu-io-syscalls.c |  140 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 158 insertions(+), 0 deletions(-)
 create mode 100644 qemu-io-syscalls.c

diff --git a/Makefile b/Makefile
index 4f7a55a..7921d54 100644
--- a/Makefile
+++ b/Makefile
@@ -85,6 +85,7 @@ OBJS+=sd.o ssi-sd.o
 OBJS+=bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
 OBJS+=buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o
 OBJS+=qemu-char.o aio.o net-checksum.o savevm.o cache-utils.o
+OBJS+=qemu-io-syscalls.o
 
 ifdef CONFIG_BRLAPI
 OBJS+= baum.o
diff --git a/configure b/configure
index c3fbbbe..a873cf4 100755
--- a/configure
+++ b/configure
@@ -1037,6 +1037,17 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
 fi
 
 ##########################################
+# preadv probe
+cat > $TMPC <<EOF
+#include <unistd.h>
+int main(void) { preadv; }
+EOF
+preadv=no
+if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
+  preadv=yes
+fi
+
+##########################################
 # fdt probe
 if test "$fdt" = "yes" ; then
     fdt=no
@@ -1432,6 +1443,9 @@ fi
 if test "$iovec" = "yes" ; then
   echo "#define HAVE_IOVEC 1" >> $config_h
 fi
+if test "$preadv" = "yes" ; then
+  echo "#define HAVE_PREADV 1" >> $config_h
+fi
 if test "$fdt" = "yes" ; then
   echo "#define HAVE_FDT 1" >> $config_h
   echo "FDT_LIBS=-lfdt" >> $config_mak
diff --git a/qemu-common.h b/qemu-common.h
index 42d5e49..0dfc575 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -204,6 +204,9 @@ void qemu_iovec_destroy(QEMUIOVector *qiov);
 void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf);
 void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count);
 
+ssize_t qemu_preadv(int fd, QEMUIOVector *qiov, off_t offset);
+ssize_t qemu_pwritev(int fd, QEMUIOVector *qiov, off_t offset);
+
 #endif /* dyngen-exec.h hack */
 
 #endif
diff --git a/qemu-io-syscalls.c b/qemu-io-syscalls.c
new file mode 100644
index 0000000..f96e35a
--- /dev/null
+++ b/qemu-io-syscalls.c
@@ -0,0 +1,140 @@
+/*
+ *  preadv/pwritev implementation
+ *  (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; under version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include <qemu-common.h>
+#include <unistd.h>
+
+/* --------------------------------------------------------------- */
+/* linux: preadv/pwritev syscall windup                            */
+
+#ifndef HAVE_PREADV
+# ifdef __linux__
+#  include <sys/syscall.h>
+
+#if 0
+/* WARNING: Be sure you know what you are doing if you enable this.
+ * linux syscall code isn't upstream yet, syscall numbers are subject
+ * to change */
+#  ifndef __NR_preadv
+#   ifdef __i386__
+#    define __NR_preadv  333
+#    define __NR_pwritev 334
+#   endif
+#   ifdef __x86_64__
+#    define __NR_preadv  295
+#    define __NR_pwritev 296
+#   endif
+#  endif
+#endif
+
+#  ifdef __NR_preadv
+#   define HAVE_PREADV 1
+
+static ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+{
+    uint32_t pos_high = (offset >> 32) & 0xffffffff;
+    uint32_t pos_low  =  offset        & 0xffffffff;
+
+    return syscall(__NR_preadv, fd, iov, iovcnt, pos_high, pos_low);
+}
+
+static ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+{
+    uint32_t pos_high = (offset >> 32) & 0xffffffff;
+    uint32_t pos_low  =  offset        & 0xffffffff;
+
+    return syscall(__NR_pwritev, fd, iov, iovcnt, pos_high, pos_low);
+}
+
+#  endif /* __NR_preadv */
+# endif /* __linux__ */
+
+#endif /* HAVE_PREADV */
+
+/* --------------------------------------------------------------- */
+/* preadv/pwritev emulation                                        */
+
+static ssize_t emulate_prwv(int fd, QEMUIOVector *qiov,
+                            off_t offset, int is_write)
+{
+    uint8_t *buf;
+    ssize_t ret;
+
+    buf = malloc(qiov->size);
+    if (NULL == buf) {
+        errno = ENOMEM;
+        return -1;
+    }
+
+    if (is_write) {
+        qemu_iovec_to_buffer(qiov, buf);
+        ret = pwrite(fd, buf, qiov->size, offset);
+    } else {
+        ret = pread(fd, buf, qiov->size, offset);
+        if (ret > 0)
+            qemu_iovec_from_buffer(qiov, buf, ret);
+    }
+
+    free(buf);
+    return ret;
+}
+
+/* --------------------------------------------------------------- */
+/* qemu preadv/pwritev interface */
+
+#ifdef HAVE_PREADV
+static int preadv_present = 1;
+#endif
+
+ssize_t qemu_preadv(int fd, QEMUIOVector *qiov, off_t offset)
+{
+#ifdef HAVE_PREADV
+    ssize_t ret;
+
+    if (preadv_present) {
+        ret = preadv(fd, qiov->iov, qiov->niov, offset);
+        if (ret < 0 && errno == ENOSYS) {
+            preadv_present = 0;
+            goto emulate;
+        }
+        return ret;
+    }
+emulate:
+#endif
+
+    return emulate_prwv(fd, qiov, offset, 0);
+}
+
+ssize_t qemu_pwritev(int fd, QEMUIOVector *qiov, off_t offset)
+{
+#ifdef HAVE_PREADV
+    ssize_t ret;
+
+    if (preadv_present) {
+        ret = pwritev(fd, qiov->iov, qiov->niov, offset);
+        if (ret < 0 && errno == ENOSYS) {
+            preadv_present = 0;
+            goto emulate;
+        }
+        return ret;
+    }
+emulate:
+#endif
+
+    return emulate_prwv(fd, qiov, offset, 1);
+}
-- 
1.6.1.3


  parent reply	other threads:[~2009-03-16 11:38 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-14 19:27 [Qemu-devel] [PATCH 0/6] add real vectored block I/O support Christoph Hellwig
2009-03-14 19:27 ` [Qemu-devel] [PATCH 1/6] more BlockDriver C99 initializers Christoph Hellwig
2009-03-28 18:35   ` Christoph Hellwig
2009-03-14 19:28 ` [Qemu-devel] [PATCH 2/6] change vectored block I/O API to plain iovecs Christoph Hellwig
2009-03-15 12:42   ` Avi Kivity
2009-03-15 13:20     ` Anthony Liguori
2009-03-15 13:36       ` Avi Kivity
2009-03-15 14:48     ` Christoph Hellwig
2009-03-15 15:07       ` Avi Kivity
2009-03-15 16:35         ` Christoph Hellwig
2009-03-14 19:28 ` [Qemu-devel] [PATCH 3/6] virtio-blk: use generic vectored I/O APIs Christoph Hellwig
2009-03-14 19:30 ` [Qemu-devel] [PATCH 4/6] remove bdrv_aio_read/bdrv_aio_write Christoph Hellwig
2009-03-14 19:30 ` [Qemu-devel] [PATCH 5/6] push down vector linearization to posix-aio-compat.c Christoph Hellwig
2009-03-14 19:31 ` [Qemu-devel] [PATCH 6/6] experimental native preadv/pwritev support for Linux Christoph Hellwig
2009-03-15 14:36   ` Blue Swirl
2009-03-15 14:44     ` Christoph Hellwig
2009-03-15 15:03       ` Blue Swirl
2009-03-15 15:16         ` Christoph Hellwig
2009-03-16 11:38   ` Gerd Hoffmann [this message]
2009-03-16 11:53     ` Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49BE3A30.6060205@redhat.com \
    --to=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).