All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.