From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LjB9Q-0006UE-5N for qemu-devel@nongnu.org; Mon, 16 Mar 2009 07:38:36 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LjB9K-0006Tn-FB for qemu-devel@nongnu.org; Mon, 16 Mar 2009 07:38:34 -0400 Received: from [199.232.76.173] (port=49165 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LjB9K-0006Td-2M for qemu-devel@nongnu.org; Mon, 16 Mar 2009 07:38:30 -0400 Received: from mx2.redhat.com ([66.187.237.31]:51724) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LjB9J-0006g9-EZ for qemu-devel@nongnu.org; Mon, 16 Mar 2009 07:38:29 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n2GBcS2l027582 for ; Mon, 16 Mar 2009 07:38:28 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n2GBcSs7018146 for ; Mon, 16 Mar 2009 07:38:28 -0400 Received: from zweiblum.home.kraxel.org (vpn-10-108.str.redhat.com [10.32.10.108]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n2GBcQDa014234 for ; Mon, 16 Mar 2009 07:38:26 -0400 Message-ID: <49BE3A30.6060205@redhat.com> Date: Mon, 16 Mar 2009 12:38:24 +0100 From: Gerd Hoffmann MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH 6/6] experimental native preadv/pwritev support for Linux References: <20090314192701.GA3497@lst.de> <20090314193127.GC3799@lst.de> In-Reply-To: <20090314193127.GC3799@lst.de> Content-Type: multipart/mixed; boundary="------------050509070906060206040807" Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------050509070906060206040807 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit 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 --------------050509070906060206040807 Content-Type: text/plain; name="0001-preadv-writev-code-for-qemu.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="0001-preadv-writev-code-for-qemu.patch" >>From 5ab001859f3abeb792ef22d073d2bc38f6bb8604 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann 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 < +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 + * + * 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 +#include + +/* --------------------------------------------------------------- */ +/* linux: preadv/pwritev syscall windup */ + +#ifndef HAVE_PREADV +# ifdef __linux__ +# include + +#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 --------------050509070906060206040807--