* 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
This commit is contained in:
parent
a6ba76a6cd
commit
e5d3ecb4f1
|
@ -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 @@ struct rumpuser_aio {
|
|||
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;
|
||||
|
|
|
@ -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 @@ __RCSID("$NetBSD: rumpuser_pth.c,v 1.32 2009/04/26 22:26:59 pooka Exp $");
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/rumpuser.h>
|
||||
|
||||
|
@ -129,6 +130,8 @@ iothread(void *arg)
|
|||
{
|
||||
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 @@ iothread(void *arg)
|
|||
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));
|
||||
|
|
|
@ -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 @@ struct blkwin {
|
|||
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 @@ static struct rblkdev {
|
|||
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 @@ getwindow(struct rblkdev *rblk, off_t off, int *wsize, int *error)
|
|||
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 @@ getwindow(struct rblkdev *rblk, off_t off, int *wsize, int *error)
|
|||
|
||||
/* 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 @@ getwindow(struct rblkdev *rblk, off_t off, int *wsize, int *error)
|
|||
}
|
||||
} 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 @@ rumpblk_init(void)
|
|||
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 @@ rumpblk_open(dev_t dev, int flag, int fmt, struct lwp *l)
|
|||
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 @@ dostrategy(struct buf *bp)
|
|||
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 @@ dostrategy(struct buf *bp)
|
|||
|
||||
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 @@ dostrategy(struct buf *bp)
|
|||
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 @@ dostrategy(struct buf *bp)
|
|||
*
|
||||
* 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 @@ dostrategy(struct buf *bp)
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue