Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Rework how the bio hypercalls work, part 1/n:



details:   https://anonhg.NetBSD.org/src/rev/5461022696d4
branches:  trunk
changeset: 786464:5461022696d4
user:      pooka <pooka%NetBSD.org@localhost>
date:      Mon Apr 29 12:56:03 2013 +0000

description:
Rework how the bio hypercalls work, part 1/n:

Reduce the set of hypercalls to one: "do block i/o".  This not only
eliminates a lot of pseudo-duplicate code, it also gives the
hypervisor a lot more freedom on how to optimize the i/o.

diffstat:

 lib/librumpuser/Makefile            |    4 +-
 lib/librumpuser/rumpuser.c          |   36 +-------
 lib/librumpuser/rumpuser_bio.c      |  173 ++++++++++++++++++++++++++++++++++++
 lib/librumpuser/rumpuser_int.h      |   14 ++-
 lib/librumpuser/rumpuser_pth.c      |   86 +-----------------
 sys/rump/include/rump/rumpuser.h    |   49 ++-------
 sys/rump/librump/rumpvfs/rump_vfs.c |   10 +-
 sys/rump/librump/rumpvfs/rumpblk.c  |   84 ++--------------
 8 files changed, 220 insertions(+), 236 deletions(-)

diffs (truncated from 645 to 300 lines):

diff -r 253b0551945d -r 5461022696d4 lib/librumpuser/Makefile
--- a/lib/librumpuser/Makefile  Mon Apr 29 12:47:14 2013 +0000
+++ b/lib/librumpuser/Makefile  Mon Apr 29 12:56:03 2013 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.9 2013/03/18 13:14:10 pooka Exp $
+#      $NetBSD: Makefile,v 1.10 2013/04/29 12:56:04 pooka Exp $
 #
 
 WARNS?=                5
@@ -13,7 +13,7 @@
 
 SRCS=          rumpuser.c
 SRCS+=         rumpuser_pth.c
-SRCS+=         rumpuser_dl.c rumpuser_sp.c rumpuser_daemonize.c
+SRCS+=         rumpuser_dl.c rumpuser_sp.c rumpuser_daemonize.c rumpuser_bio.c
 SRCS+=         rumpuser_component.c
 
 INCSDIR=       /usr/include/rump
diff -r 253b0551945d -r 5461022696d4 lib/librumpuser/rumpuser.c
--- a/lib/librumpuser/rumpuser.c        Mon Apr 29 12:47:14 2013 +0000
+++ b/lib/librumpuser/rumpuser.c        Mon Apr 29 12:56:03 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rumpuser.c,v 1.37 2013/04/28 13:39:13 pooka Exp $      */
+/*     $NetBSD: rumpuser.c,v 1.38 2013/04/29 12:56:04 pooka Exp $      */
 
 /*
  * Copyright (c) 2007-2010 Antti Kantee.  All Rights Reserved.
@@ -28,7 +28,7 @@
 #include "rumpuser_port.h"
 
 #if !defined(lint)
-__RCSID("$NetBSD: rumpuser.c,v 1.37 2013/04/28 13:39:13 pooka Exp $");
+__RCSID("$NetBSD: rumpuser.c,v 1.38 2013/04/29 12:56:04 pooka Exp $");
 #endif /* !lint */
 
 #include <sys/ioctl.h>
@@ -403,22 +403,6 @@
        return rv;
 }
 
-void
-rumpuser_read_bio(int fd, void *data, size_t size, off_t offset,
-       rump_biodone_fn biodone, void *biodonecookie)
-{
-       ssize_t rv;
-       int error = 0;
-
-       rv = rumpuser_pread(fd, data, size, offset, &error);
-       /* check against <0 instead of ==-1 to get typing below right */
-       if (rv < 0)
-               rv = 0;
-
-       /* LINTED: see above */
-       biodone(biodonecookie, rv, error);
-}
-
 ssize_t
 rumpuser_write(int fd, const void *data, size_t size, int *error)
 {
@@ -443,22 +427,6 @@
        return rv;
 }
 
-void
-rumpuser_write_bio(int fd, const void *data, size_t size, off_t offset,
-       rump_biodone_fn biodone, void *biodonecookie)
-{
-       ssize_t rv;
-       int error = 0;
-
-       rv = rumpuser_pwrite(fd, data, size, offset, &error);
-       /* check against <0 instead of ==-1 to get typing below right */
-       if (rv < 0)
-               rv = 0;
-
-       /* LINTED: see above */
-       biodone(biodonecookie, rv, error);
-}
-
 ssize_t
 rumpuser_readv(int fd, const struct rumpuser_iovec *riov, int iovcnt,
        int *error)
diff -r 253b0551945d -r 5461022696d4 lib/librumpuser/rumpuser_bio.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/librumpuser/rumpuser_bio.c    Mon Apr 29 12:56:03 2013 +0000
@@ -0,0 +1,173 @@
+/*     $NetBSD: rumpuser_bio.c,v 1.1 2013/04/29 12:56:04 pooka Exp $   */
+
+/*-
+ * Copyright (c) 2013 Antti Kantee.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "rumpuser_port.h"
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rump/rumpuser.h>
+
+#include "rumpuser_int.h"
+
+struct rumpuser_bio {
+       int bio_fd;
+       int bio_op;
+       void *bio_data;
+       size_t bio_dlen;
+       off_t bio_off;
+
+       rump_biodone_fn bio_done;
+       void *bio_donearg;
+};
+
+#define N_BIOS 128
+static pthread_mutex_t biomtx = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t biocv = PTHREAD_COND_INITIALIZER;
+static int bio_head, bio_tail;
+static struct rumpuser_bio bios[N_BIOS];
+
+static void
+dobio(struct rumpuser_bio *biop)
+{
+       ssize_t rv;
+       int error, dummy;
+
+       assert(biop->bio_donearg != NULL);
+       if (biop->bio_op & RUMPUSER_BIO_READ) {
+               error = 0;
+               rv = pread(biop->bio_fd, biop->bio_data,
+                   biop->bio_dlen, biop->bio_off);
+               if (rv < 0) {
+                       rv = 0;
+                       error = errno;
+               }
+       } else {
+               error = 0;
+               rv = pwrite(biop->bio_fd, biop->bio_data,
+                   biop->bio_dlen, biop->bio_off);
+               if (rv < 0) {
+                       rv = 0;
+                       error = errno;
+               } else if (biop->bio_op & RUMPUSER_BIO_SYNC) {
+#ifdef __NetBSD__
+                       fsync_range(biop->bio_fd, FDATASYNC,
+                           biop->bio_off, biop->bio_dlen);
+#else
+                       fsync(biop->bio_fd);
+#endif
+               }
+       }
+       rumpuser__reschedule(0, NULL);
+       biop->bio_done(biop->bio_donearg, (size_t)rv, error);
+       rumpuser__unschedule(0, &dummy, NULL);
+
+       /* paranoia */
+       biop->bio_donearg = NULL;
+}
+
+static void *
+biothread(void *arg)
+{
+       struct rumpuser_bio *biop;
+
+       NOFAIL_ERRNO(pthread_mutex_lock(&biomtx));
+       for (;;) {
+               while (bio_head == bio_tail)
+                       NOFAIL_ERRNO(pthread_cond_wait(&biocv, &biomtx));
+
+               biop = &bios[bio_tail];
+               pthread_mutex_unlock(&biomtx);
+
+               dobio(biop);
+
+               NOFAIL_ERRNO(pthread_mutex_lock(&biomtx));
+               bio_tail = (bio_tail+1) % N_BIOS;
+               pthread_cond_signal(&biocv);
+       }
+
+       /* unreachable */
+       abort();
+}
+
+void
+rumpuser_bio(int fd, int op, void *data, size_t dlen, off_t doff,
+       rump_biodone_fn biodone, void *bioarg)
+{
+       struct rumpuser_bio bio;
+       static int inited = 0;
+       static int usethread = 0;
+
+       if (!inited) {
+               pthread_mutex_lock(&biomtx);
+               if (!inited) {
+                       char buf[16];
+                       pthread_t pt;
+
+                       /*
+                        * duplicates policy of rump kernel.  maybe a bit
+                        * questionable, but since the setting is not
+                        * used in normal circumstances, let's not care
+                        */
+                       if (getenv_r("RUMP_THREADS", buf, sizeof(buf)) == 0)
+                               usethread = *buf != '0';
+
+                       pthread_create(&pt, NULL, biothread, NULL);
+                       inited = 1;
+               }
+               pthread_mutex_unlock(&biomtx);
+               assert(inited);
+       }
+
+       bio.bio_fd = fd;
+       bio.bio_op = op;
+       bio.bio_data = data;
+       bio.bio_dlen = dlen;
+       bio.bio_off = doff;
+       bio.bio_done = biodone;
+       bio.bio_donearg = bioarg;
+
+       if (!usethread) {
+               dobio(&bio);
+       } else {
+               pthread_mutex_lock(&biomtx);
+               while ((bio_head+1) % N_BIOS == bio_tail)
+                       pthread_cond_wait(&biocv, &biomtx);
+
+               bios[bio_head] = bio;
+               bio_head = (bio_head+1) % N_BIOS;
+
+               pthread_cond_signal(&biocv);
+               pthread_mutex_unlock(&biomtx);
+       }
+}
diff -r 253b0551945d -r 5461022696d4 lib/librumpuser/rumpuser_int.h
--- a/lib/librumpuser/rumpuser_int.h    Mon Apr 29 12:47:14 2013 +0000
+++ b/lib/librumpuser/rumpuser_int.h    Mon Apr 29 12:56:03 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rumpuser_int.h,v 1.5 2013/04/27 14:59:08 pooka Exp $   */
+/*     $NetBSD: rumpuser_int.h,v 1.6 2013/04/29 12:56:04 pooka Exp $   */
 
 /*
  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
@@ -68,3 +68,15 @@
 }
 
 void rumpuser__thrinit(void);
+
+#define NOFAIL(a) do {if (!(a)) abort();} while (/*CONSTCOND*/0)
+
+#define NOFAIL_ERRNO(a)                                                        \
+do {                                                                   \
+       int fail_rv = (a);                                              \
+       if (fail_rv) {                                                  \
+               printf("panic: rumpuser fatal failure %d (%s)\n",       \
+                   fail_rv, strerror(fail_rv));                        \
+               abort();                                                \
+       }                                                               \
+} while (/*CONSTCOND*/0)
diff -r 253b0551945d -r 5461022696d4 lib/librumpuser/rumpuser_pth.c
--- a/lib/librumpuser/rumpuser_pth.c    Mon Apr 29 12:47:14 2013 +0000
+++ b/lib/librumpuser/rumpuser_pth.c    Mon Apr 29 12:56:03 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rumpuser_pth.c,v 1.16 2013/04/28 13:37:51 pooka Exp $  */
+/*     $NetBSD: rumpuser_pth.c,v 1.17 2013/04/29 12:56:04 pooka Exp $  */
 
 /*
  * Copyright (c) 2007-2010 Antti Kantee.  All Rights Reserved.
@@ -28,7 +28,7 @@
 #include "rumpuser_port.h"
 
 #if !defined(lint)
-__RCSID("$NetBSD: rumpuser_pth.c,v 1.16 2013/04/28 13:37:51 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_pth.c,v 1.17 2013/04/29 12:56:04 pooka Exp $");
 #endif /* !lint */



Home | Main Index | Thread Index | Old Index