Module Name: src
Committed By: pooka
Date: Mon Apr 27 14:28:58 UTC 2009
Modified Files:
src/sys/rump/include/rump: rumpuser.h
src/sys/rump/librump/rumpuser: rumpuser_pth.c
src/sys/rump/librump/rumpvfs: rumpblk.c
Log Message:
* expand syncing logic into rumpuser, since it has more freedom on
how to do it (e.g. fsync_range)
* hash out O_DIRECT support. it's the fastest method of safely operating
on a file, but we can't currently autodetect support, so it's not
enabled by default
* sprinkle more event counters
To generate a diff of this commit:
cvs rdiff -u -r1.22 -r1.23 src/sys/rump/include/rump/rumpuser.h
cvs rdiff -u -r1.32 -r1.33 src/sys/rump/librump/rumpuser/rumpuser_pth.c
cvs rdiff -u -r1.19 -r1.20 src/sys/rump/librump/rumpvfs/rumpblk.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/rump/include/rump/rumpuser.h
diff -u src/sys/rump/include/rump/rumpuser.h:1.22 src/sys/rump/include/rump/rumpuser.h:1.23
--- src/sys/rump/include/rump/rumpuser.h:1.22 Sun Apr 26 21:39:10 2009
+++ src/sys/rump/include/rump/rumpuser.h Mon Apr 27 14:28:58 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpuser.h,v 1.22 2009/04/26 21:39:10 pooka Exp $ */
+/* $NetBSD: rumpuser.h,v 1.23 2009/04/27 14:28:58 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@@ -155,6 +155,9 @@
void *rua_bp;
int rua_op;
};
+#define RUA_OP_READ 0x01
+#define RUA_OP_WRITE 0x02
+#define RUA_OP_SYNC 0x04
#define N_AIOS 1024
extern struct rumpuser_mtx rumpuser_aio_mtx;
Index: src/sys/rump/librump/rumpuser/rumpuser_pth.c
diff -u src/sys/rump/librump/rumpuser/rumpuser_pth.c:1.32 src/sys/rump/librump/rumpuser/rumpuser_pth.c:1.33
--- src/sys/rump/librump/rumpuser/rumpuser_pth.c:1.32 Sun Apr 26 22:26:59 2009
+++ src/sys/rump/librump/rumpuser/rumpuser_pth.c Mon Apr 27 14:28:58 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpuser_pth.c,v 1.32 2009/04/26 22:26:59 pooka Exp $ */
+/* $NetBSD: rumpuser_pth.c,v 1.33 2009/04/27 14:28:58 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#if !defined(lint)
-__RCSID("$NetBSD: rumpuser_pth.c,v 1.32 2009/04/26 22:26:59 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_pth.c,v 1.33 2009/04/27 14:28:58 pooka Exp $");
#endif /* !lint */
#ifdef __linux__
@@ -46,6 +46,7 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
+#include <unistd.h>
#include <rump/rumpuser.h>
@@ -129,6 +130,8 @@
{
struct rumpuser_aio *rua;
rump_biodone_fn biodone = arg;
+ ssize_t rv;
+ int error;
NOFAIL_ERRNO(pthread_mutex_lock(&rumpuser_aio_mtx.pthmtx));
for (;;) {
@@ -141,12 +144,32 @@
assert(rua->rua_bp != NULL);
pthread_mutex_unlock(&rumpuser_aio_mtx.pthmtx);
- if (rua->rua_op)
- rumpuser_read_bio(rua->rua_fd, rua->rua_data,
- rua->rua_dlen, rua->rua_off, biodone, rua->rua_bp);
- else
- rumpuser_write_bio(rua->rua_fd, rua->rua_data,
- rua->rua_dlen, rua->rua_off, biodone, rua->rua_bp);
+ if (rua->rua_op & RUA_OP_READ) {
+ error = 0;
+ rv = pread(rua->rua_fd, rua->rua_data,
+ rua->rua_dlen, rua->rua_off);
+ if (rv < 0) {
+ rv = 0;
+ error = errno;
+ }
+ } else {
+ error = 0;
+ rv = pwrite(rua->rua_fd, rua->rua_data,
+ rua->rua_dlen, rua->rua_off);
+ if (rv < 0) {
+ rv = 0;
+ error = errno;
+ } else if (rua->rua_op & RUA_OP_SYNC) {
+#ifdef __NetBSD__
+ fsync_range(rua->rua_fd, FDATASYNC,
+ rua->rua_off, rua->rua_dlen);
+#else
+ fsync(rua->rua_fd);
+#endif
+ }
+ }
+ biodone(rua->rua_bp, rv, error);
+
rua->rua_bp = NULL;
NOFAIL_ERRNO(pthread_mutex_lock(&rumpuser_aio_mtx.pthmtx));
Index: src/sys/rump/librump/rumpvfs/rumpblk.c
diff -u src/sys/rump/librump/rumpvfs/rumpblk.c:1.19 src/sys/rump/librump/rumpvfs/rumpblk.c:1.20
--- src/sys/rump/librump/rumpvfs/rumpblk.c:1.19 Fri Apr 17 12:29:08 2009
+++ src/sys/rump/librump/rumpvfs/rumpblk.c Mon Apr 27 14:28:58 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpblk.c,v 1.19 2009/04/17 12:29:08 pooka Exp $ */
+/* $NetBSD: rumpblk.c,v 1.20 2009/04/27 14:28:58 pooka Exp $ */
/*
* Copyright (c) 2009 Antti Kantee. All Rights Reserved.
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rumpblk.c,v 1.19 2009/04/17 12:29:08 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpblk.c,v 1.20 2009/04/27 14:28:58 pooka Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@@ -89,6 +89,9 @@
static struct rblkdev {
char *rblk_path;
int rblk_fd;
+#ifdef HAS_ODIRECT
+ int rblk_dfd;
+#endif
/* for mmap */
int rblk_mmflags;
@@ -103,9 +106,15 @@
struct disklabel rblk_dl;
} minors[RUMPBLK_SIZE];
-static struct evcnt memblk_ev_reqs;
-static struct evcnt memblk_ev_hits;
-static struct evcnt memblk_ev_busy;
+static struct evcnt ev_io_total;
+static struct evcnt ev_io_async;
+
+static struct evcnt ev_memblk_hits;
+static struct evcnt ev_memblk_busy;
+
+static struct evcnt ev_bwrite_total;
+static struct evcnt ev_bwrite_async;
+static struct evcnt ev_bread_total;
dev_type_open(rumpblk_open);
dev_type_close(rumpblk_close);
@@ -143,7 +152,6 @@
struct blkwin *win;
mutex_enter(&rblk->rblk_memmtx);
- memblk_ev_reqs.ev_count++;
retry:
/* search for window */
TAILQ_FOREACH(win, &rblk->rblk_lruq, win_lru) {
@@ -153,7 +161,7 @@
/* found? return */
if (win) {
- memblk_ev_hits.ev_count++;
+ ev_memblk_hits.ev_count++;
TAILQ_REMOVE(&rblk->rblk_lruq, win, win_lru);
goto good;
}
@@ -189,7 +197,7 @@
}
} else {
DPRINTF(("memwin wait\n"));
- memblk_ev_busy.ev_count++;
+ ev_memblk_busy.ev_count++;
rblk->rblk_waiting = true;
cv_wait(&rblk->rblk_memcv, &rblk->rblk_memmtx);
@@ -288,11 +296,21 @@
cv_init(&minors[i].rblk_memcv, "rblkmcv");
}
- evcnt_attach_dynamic(&memblk_ev_reqs, EVCNT_TYPE_MISC, NULL,
- "rumpblk", "memblk requests");
- evcnt_attach_dynamic(&memblk_ev_hits, EVCNT_TYPE_MISC, NULL,
+ evcnt_attach_dynamic(&ev_io_total, EVCNT_TYPE_MISC, NULL,
+ "rumpblk", "rumpblk I/O reqs");
+ evcnt_attach_dynamic(&ev_io_async, EVCNT_TYPE_MISC, NULL,
+ "rumpblk", "rumpblk async I/O");
+
+ evcnt_attach_dynamic(&ev_bread_total, EVCNT_TYPE_MISC, NULL,
+ "rumpblk", "rumpblk bytes read");
+ evcnt_attach_dynamic(&ev_bwrite_total, EVCNT_TYPE_MISC, NULL,
+ "rumpblk", "rumpblk bytes written");
+ evcnt_attach_dynamic(&ev_bwrite_async, EVCNT_TYPE_MISC, NULL,
+ "rumpblk", "rumpblk bytes written async");
+
+ evcnt_attach_dynamic(&ev_memblk_hits, EVCNT_TYPE_MISC, NULL,
"rumpblk", "memblk window hits");
- evcnt_attach_dynamic(&memblk_ev_busy, EVCNT_TYPE_MISC, NULL,
+ evcnt_attach_dynamic(&ev_memblk_busy, EVCNT_TYPE_MISC, NULL,
"rumpblk", "memblk all windows busy");
if (blkfail) {
@@ -345,6 +363,13 @@
return error;
}
+#ifdef HAS_ODIRECT
+ rblk->rblk_dfd = rumpuser_open(rblk->rblk_path,
+ OFLAGS(flag) | O_DIRECT, &error);
+ if (error)
+ return error;
+#endif
+
if (ft == RUMPUSER_FT_REG) {
struct blkwin *win;
int i, winsize;
@@ -465,6 +490,18 @@
off_t off;
int async, error;
+ /* collect statistics */
+ ev_io_total.ev_count++;
+ if (async)
+ ev_io_async.ev_count++;
+ if (BUF_ISWRITE(bp)) {
+ ev_bwrite_total.ev_count += bp->b_bcount;
+ if (async)
+ ev_bwrite_async.ev_count += bp->b_bcount;
+ } else {
+ ev_bread_total.ev_count++;
+ }
+
off = bp->b_blkno << DEV_BSHIFT;
/*
* Do bounds checking if we're working on a file. Otherwise
@@ -492,9 +529,9 @@
async = bp->b_flags & B_ASYNC;
DPRINTF(("rumpblk_strategy: 0x%x bytes %s off 0x%" PRIx64
- " (0x%" PRIx64 " - 0x%" PRIx64 ")\n",
+ " (0x%" PRIx64 " - 0x%" PRIx64 "), %ssync\n",
bp->b_bcount, BUF_ISREAD(bp) ? "READ" : "WRITE",
- off, off, (off + bp->b_bcount)));
+ off, off, (off + bp->b_bcount), async ? "a" : ""));
/* mmap? handle here and return */
if (rblk->rblk_mmflags) {
@@ -534,7 +571,6 @@
return;
}
-
/*
* Do I/O. We have different paths for async and sync I/O.
* Async I/O is done by passing a request to rumpuser where
@@ -547,32 +583,47 @@
*
* Using bufq here might be a good idea.
*/
+
if (rump_threads) {
struct rumpuser_aio *rua;
+ int op, fd;
+
+ fd = rblk->rblk_fd;
+ if (BUF_ISREAD(bp)) {
+ op = RUA_OP_READ;
+ } else {
+ op = RUA_OP_WRITE;
+ if (!async) {
+ /* O_DIRECT not fully automatic yet */
+#ifdef HAS_ODIRECT
+ if ((off & (DEV_BSIZE-1)) == 0
+ && ((intptr_t)bp->b_data&(DEV_BSIZE-1)) == 0
+ && (bp->b_bcount & (DEV_BSIZE-1)) == 0)
+ fd = rblk->rblk_dfd;
+ else
+#endif
+ op |= RUA_OP_SYNC;
+ }
+ }
rumpuser_mutex_enter(&rumpuser_aio_mtx);
- while ((rumpuser_aio_head+1) % N_AIOS == rumpuser_aio_tail)
+ while ((rumpuser_aio_head+1) % N_AIOS == rumpuser_aio_tail) {
rumpuser_cv_wait(&rumpuser_aio_cv, &rumpuser_aio_mtx);
+ }
rua = &rumpuser_aios[rumpuser_aio_head];
KASSERT(rua->rua_bp == NULL);
- rua->rua_fd = rblk->rblk_fd;
+ rua->rua_fd = fd;
rua->rua_data = bp->b_data;
rua->rua_dlen = bp->b_bcount;
rua->rua_off = off;
rua->rua_bp = bp;
- rua->rua_op = BUF_ISREAD(bp);
+ rua->rua_op = op;
/* insert into queue & signal */
rumpuser_aio_head = (rumpuser_aio_head+1) % N_AIOS;
rumpuser_cv_signal(&rumpuser_aio_cv);
rumpuser_mutex_exit(&rumpuser_aio_mtx);
-
- /* make sure non-async writes end up on backing media */
- if (BUF_ISWRITE(bp) && !async) {
- biowait(bp);
- rumpuser_fsync(rblk->rblk_fd, &error);
- }
} else {
if (BUF_ISREAD(bp)) {
rumpuser_read_bio(rblk->rblk_fd, bp->b_data,
@@ -581,10 +632,8 @@
rumpuser_write_bio(rblk->rblk_fd, bp->b_data,
bp->b_bcount, off, rump_biodone, bp);
}
- if (!async) {
- if (BUF_ISWRITE(bp))
- rumpuser_fsync(rblk->rblk_fd, &error);
- }
+ if (BUF_ISWRITE(bp) && !async)
+ rumpuser_fsync(rblk->rblk_fd, &error);
}
}