From: Christoph Hellwig <hch@lst.de>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 6/6] experimental native preadv/pwritev support for Linux
Date: Sat, 14 Mar 2009 20:31:27 +0100 [thread overview]
Message-ID: <20090314193127.GC3799@lst.de> (raw)
In-Reply-To: <20090314192701.GA3497@lst.de>
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.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: qemu/posix-aio-compat.c
===================================================================
--- qemu.orig/posix-aio-compat.c 2009-03-14 18:30:35.000000000 +0100
+++ qemu/posix-aio-compat.c 2009-03-14 18:30:36.000000000 +0100
@@ -76,6 +76,45 @@ static void thread_create(pthread_t *thr
if (ret) die2(ret, "pthread_create");
}
+#if defined (__linux__) && defined(__i386__)
+
+#define __NR_preadv 333
+#define __NR_pwritev 334
+
+static ssize_t
+qemu_preadv(int fd, const struct iovec *iov, int nr_iov, off_t offset)
+{
+ uint32_t pos_high = offset >> 32;
+ uint32_t pos_low = offset;
+
+ return syscall(__NR_preadv, fd, iov, (unsigned long)nr_iov, pos_high, pos_low);
+}
+
+static ssize_t
+qemu_pwritev(int fd, const struct iovec *iov, int nr_iov, off_t offset)
+{
+ uint32_t pos_high = offset >> 32;
+ uint32_t pos_low = offset;
+
+ return syscall(__NR_pwritev, fd, iov, (unsigned long)nr_iov, pos_high, pos_low);
+}
+
+#else
+
+static ssize_t
+qemu_preadv(int fd, const struct iovec *iov, int nr_iov, off_t offset)
+{
+ return -ENOSYS;
+}
+
+static ssize_t
+qemu_pwritev(int fd, const struct iovec *iov, int nr_iov, off_t offset)
+{
+ return -ENOSYS;
+}
+
+#endif
+
/*
* Check if we need to copy the data in the aiocb into a new
* properly aligned buffer.
@@ -93,6 +132,29 @@ static int aiocb_needs_copy(struct qemu_
return 0;
}
+static size_t handle_aiocb_vector(struct qemu_paiocb *aiocb)
+{
+ size_t offset = 0;
+ ssize_t len;
+
+ do {
+ if (aiocb->is_write)
+ len = qemu_pwritev(aiocb->aio_fildes,
+ aiocb->aio_iov,
+ aiocb->aio_niov,
+ aiocb->aio_offset + offset);
+ else
+ len = qemu_preadv(aiocb->aio_fildes,
+ aiocb->aio_iov,
+ aiocb->aio_niov,
+ aiocb->aio_offset + offset);
+ } while (len == -1 && errno == EINTR);
+
+ if (len == -1)
+ return -errno;
+ return len;
+}
+
static size_t handle_aiocb_linear(struct qemu_paiocb *aiocb, char *buf)
{
size_t offset = 0;
@@ -129,12 +191,31 @@ static size_t handle_aiocb(struct qemu_p
size_t nbytes;
char *buf;
- if (!aiocb_needs_copy(aiocb) && aiocb->aio_niov == 1) {
+ if (!aiocb_needs_copy(aiocb)) {
/*
* If there is just a single buffer, and it is properly aligned
* we can just use plain pread/pwrite without any problems.
*/
- return handle_aiocb_linear(aiocb, aiocb->aio_iov->iov_base);
+ if (aiocb->aio_niov == 1)
+ return handle_aiocb_linear(aiocb, aiocb->aio_iov->iov_base);
+
+ /*
+ * We have more than one iovec, and all are properly aligned.
+ *
+ * Try preadv/pwritev first and fall back to linearizing the
+ * buffer if it's not supported.
+ */
+ nbytes = handle_aiocb_vector(aiocb);
+ if (nbytes == aiocb->aio_nbytes)
+ return nbytes;
+ if (nbytes < 0 && nbytes != -ENOSYS)
+ return nbytes;
+
+ /*
+ * XXX(hch): short read/write. no easy way to handle the reminder
+ * using these interfaces. For now retry using plain
+ * pread/pwrite?
+ */
}
/*
next prev parent reply other threads:[~2009-03-14 19:31 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 ` Christoph Hellwig [this message]
2009-03-15 14:36 ` [Qemu-devel] [PATCH 6/6] experimental native preadv/pwritev support for Linux 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
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=20090314193127.GC3799@lst.de \
--to=hch@lst.de \
--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).