svn commit: r200455 - in
user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs:
. sys
Kip Macy
kmacy at FreeBSD.org
Sat Dec 12 23:41:15 UTC 2009
Author: kmacy
Date: Sat Dec 12 23:41:15 2009
New Revision: 200455
URL: http://svn.freebsd.org/changeset/base/200455
Log:
- create _locked versions of zbio_buf_evict_overlap and zbio_buf_vm_object_insert
- minimize hold time of vm page queue lock
- mark B_MALLOC buffers B_CACHE if they reflect contents of cached pages
- add symbolic defines to clarify intent of calls to _evict_overlap
- update io pipeline to bypass io to disk if read from page cache succeeded or getblk
successfully obtained all cached pages
Modified:
user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_bio.h
user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_bio.c
user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
Modified: user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_bio.h
==============================================================================
--- user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_bio.h Sat Dec 12 23:16:47 2009 (r200454)
+++ user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_bio.h Sat Dec 12 23:41:15 2009 (r200455)
@@ -34,7 +34,7 @@ $FreeBSD$
#define ZBIO_BUF_CLONING (1 << 30) /* is being cloned */
-void zbio_sync_cache(spa_t *spa, blkptr_t *bp, uint64_t txg, void *data, uint64_t size, int bio_op);
+int zbio_sync_cache(spa_t *spa, blkptr_t *bp, uint64_t txg, void *data, uint64_t size, int bio_op);
void zbio_getblk(arc_buf_t *buf);
void zbio_data_getblk(arc_buf_t *buf);
void zbio_relse(arc_buf_t *buf, size_t size);
Modified: user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_bio.c
==============================================================================
--- user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_bio.c Sat Dec 12 23:16:47 2009 (r200454)
+++ user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_bio.c Sat Dec 12 23:41:15 2009 (r200455)
@@ -122,9 +122,13 @@ MALLOC_DEFINE(M_ZFS_BIO, "zfs_bio", "zfs
#define B_CLONED B_00001000
#define B_ASSIGNED B_00004000
-#define ZB_EVICT_ALL 0x1
-#define ZB_COPYIN 0x2
-#define ZB_COPYOUT 0x3
+#define ZB_EVICT_ALL 0x1
+#define ZB_EVICT_BUFFERED 0x2
+
+#define ZB_COPYIN 0x2
+#define ZB_COPYOUT 0x3
+
+#define NO_TXG 0x0
#define btos(nbytes) ((nbytes)>>DEV_BSHIFT)
#define stob(nsectors) ((nsectors)<<DEV_BSHIFT)
@@ -529,7 +533,9 @@ zbio_buf_vm_object_copy(buf_t *bp, int d
memcpy(va, bp->b_data + PAGE_SIZE*i, size);
sf_buf_free(sf);
}
-
+ bp->b_flags &= ~B_INVAL;
+ bp->b_flags |= B_CACHE;
+
done:
bp->b_npages = 0;
VM_OBJECT_UNLOCK(object);
@@ -556,12 +562,17 @@ zbio_buf_vm_object_evict(buf_t *bp)
vm_page_t m;
VM_OBJECT_LOCK_ASSERT(zbio_buf_get_vm_object(bp), MA_OWNED);
+ vm_page_lock_queues();
+ for (i = 0; i < bp->b_npages; i++) {
+ m = bp->b_pages[i];
+ vm_pageq_remove(m);
+ }
+ vm_page_unlock_queues();
/*
* remove pages from backing vm_object
*/
for (i = 0; i < bp->b_npages; i++) {
m = bp->b_pages[i];
- vm_pageq_remove(m);
vm_page_remove(m);
m->valid = 0;
m->flags |= PG_UNMANAGED;
@@ -569,16 +580,13 @@ zbio_buf_vm_object_evict(buf_t *bp)
}
static void
-zbio_buf_vm_object_insert(buf_t *bp, int valid)
+zbio_buf_vm_object_insert_locked(buf_t *bp, struct vnode *vp,
+ vm_object_t object, int valid)
{
vm_page_t m;
vm_pindex_t start = OFF_TO_IDX(stob(bp->b_blkno));
- spa_t *spa = zbio_buf_get_spa(bp);
- struct vnode *vp = spa_get_vnode(spa);
- vm_object_t object = vp->v_object;
int i;
- VM_OBJECT_LOCK(object);
/*
* Insert buffer pages in the object
*/
@@ -588,7 +596,6 @@ zbio_buf_vm_object_insert(buf_t *bp, int
m->valid = VM_PAGE_BITS_ALL;
vm_page_insert(m, object, start + i);
m->flags &= ~PG_UNMANAGED;
- vdrop(vp);
}
vm_page_lock_queues();
for (i = 0; i < bp->b_npages; i++) {
@@ -596,8 +603,18 @@ zbio_buf_vm_object_insert(buf_t *bp, int
vm_page_enqueue(PQ_INACTIVE, m);
}
vm_page_unlock_queues();
+}
+
+static void
+zbio_buf_vm_object_insert(buf_t *bp, int valid)
+{
+ spa_t *spa = zbio_buf_get_spa(bp);
+ struct vnode *vp = spa_get_vnode(spa);
+ vm_object_t object = vp->v_object;
+
+ VM_OBJECT_LOCK(object);
+ zbio_buf_vm_object_insert_locked(bp, vp, object, valid);
VM_OBJECT_UNLOCK(object);
-
}
/*
@@ -612,8 +629,8 @@ zbio_buf_vm_object_insert(buf_t *bp, int
* This routine may not block.
*/
static void
-zbio_buf_blkno_evict_overlap(daddr_t blkno, int size, zbio_state_t *state,
- uint64_t txg, int evict_op, int locked)
+zbio_buf_evict_overlap_locked(daddr_t blkno, int size, zbio_state_t *state,
+ uint64_t txg, int evict_op, vm_object_t object)
{
buf_t *root, *tmpbp;
daddr_t blkno_end, tmpblkno, tmpblkno_end;
@@ -621,10 +638,7 @@ zbio_buf_blkno_evict_overlap(daddr_t blk
int i, collisions;
uint64_t tmptxg;
vm_pindex_t start, end;
- vm_object_t object = spa_get_vm_object(state->spa);
- if (!locked)
- VM_OBJECT_LOCK(object);
if ((root = state->blkno_root) == NULL)
goto done;
@@ -645,7 +659,7 @@ zbio_buf_blkno_evict_overlap(daddr_t blk
if (((tmpblkno >= blkno) && (tmpblkno < blkno_end)) ||
(tmpblkno_end > blkno) && (tmpblkno_end <= blkno_end) &&
- ((txg == 0) || (tmptxg < txg))) {
+ ((txg == NO_TXG) || (tmptxg < txg))) {
TAILQ_INSERT_TAIL(&clh, tmpbp, b_freelist);
collisions++;
}
@@ -680,10 +694,20 @@ done:
}
#endif
}
- if (!locked)
- VM_OBJECT_UNLOCK(object);
}
+static void
+zbio_buf_evict_overlap(daddr_t blkno, int size, zbio_state_t *state,
+ uint64_t txg, int evict_op)
+{
+ vm_object_t object = spa_get_vm_object(state->spa);
+
+ VM_OBJECT_LOCK(object);
+ zbio_buf_evict_overlap_locked(blkno, size, state, txg, evict_op, object);
+ VM_OBJECT_UNLOCK(object);
+}
+
+
/*
Cases:
@@ -737,7 +761,7 @@ _zbio_getblk_malloc(zbio_buf_hdr_t *hdr,
newbp->b_bcount = size;
if (!BUF_EMPTY(hdr) && !(hdr->b_flags & ZBIO_BUF_CLONING)) {
blkno = hdr->b_dva.dva_word[1] & ~(1ULL<<63);
- zbio_buf_blkno_evict_overlap(blkno, size, state, txg, 0, FALSE);
+ zbio_buf_evict_overlap(blkno, size, state, txg, ZB_EVICT_BUFFERED);
newbp->b_blkno = blkno;
/*
* Copy in from the page cache if found & valid
@@ -769,7 +793,7 @@ _zbio_getblk_vmio(zbio_buf_hdr_t *hdr, i
zbio_buf_va_insert(newbp, state);
} else {
blkno = hdr->b_dva.dva_word[1] & ~(1ULL<<63);
- zbio_buf_blkno_evict_overlap(blkno, size, state, 0, 0, FALSE);
+ zbio_buf_evict_overlap(blkno, size, state, NO_TXG, ZB_EVICT_BUFFERED);
while (newbp == NULL)
newbp = getblk(vp, blkno, size, 0, 0, flags | GB_LOCK_NOWAIT);
@@ -851,7 +875,7 @@ zbio_relse(arc_buf_t *buf, size_t size)
}
}
-void
+int
zbio_sync_cache(spa_t *spa, blkptr_t *blkp, uint64_t txg, void *data, uint64_t size, int bio_op)
{
buf_t *bp;
@@ -862,10 +886,11 @@ zbio_sync_cache(spa_t *spa, blkptr_t *bl
vm_object_t object = vp->v_object;
vm_pindex_t start;
vm_page_t m;
- int i;
+ int i, io_bypass = FALSE;
if (zfs_page_cache_disable)
- return;
+ return (FALSE);
+
/*
* XXX incomplete
*/
@@ -876,7 +901,7 @@ zbio_sync_cache(spa_t *spa, blkptr_t *bl
("doing I/O with cloned or evicted buffer 0x%x", bp->b_flags));
if (bp->b_flags & B_MALLOC) {
- zbio_buf_blkno_evict_overlap(blkno, size, state, txg, 0, FALSE);
+ zbio_buf_evict_overlap(blkno, size, state, txg, ZB_EVICT_BUFFERED);
if (bio_op == BIO_READ) {
/*
@@ -886,19 +911,28 @@ zbio_sync_cache(spa_t *spa, blkptr_t *bl
zbio_buf_vm_object_copyin(bp);
if (bp->b_flags & B_CACHE) {
/* update zio pipeline */
+ io_bypass = TRUE;
}
- } else
+ } else {
zbio_buf_vm_object_copyout(bp);
+ }
} else {
- zbio_buf_blkno_evict_overlap(blkno, size, state, 0, ZB_EVICT_ALL, TRUE);
+ VM_OBJECT_LOCK(object);
+ zbio_buf_evict_overlap_locked(blkno, size, state, NO_TXG,
+ ZB_EVICT_ALL, object);
bp->b_blkno = bp->b_lblkno = blkno;
bp->b_flags |= (B_VMIO|B_ASSIGNED);
- zbio_buf_vm_object_insert(bp, bio_op == BIO_WRITE);
+ zbio_buf_vm_object_insert_locked(bp, vp, object, bio_op == BIO_WRITE);
+ VM_OBJECT_UNLOCK(object);
}
} else {
bp = zbio_buf_blkno_lookup(state, blkno);
+ if (bio_op == BIO_READ && (bp->b_flags & (B_CACHE|B_INVAL)) == B_CACHE)
+ io_bypass = TRUE;
KASSERT(bp != NULL, ("blkno=%ld data=%p unmanaged", blkno, bp->b_data));
}
+
+ return (io_bypass);
}
static void
Modified: user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
==============================================================================
--- user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c Sat Dec 12 23:16:47 2009 (r200454)
+++ user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c Sat Dec 12 23:41:15 2009 (r200455)
@@ -413,6 +413,7 @@ zio_create(zio_t *pio, spa_t *spa, uint6
const zbookmark_t *zb, uint8_t stage, uint32_t pipeline)
{
zio_t *zio;
+ int io_bypass;
ASSERT3U(size, <=, SPA_MAXBLOCKSIZE);
ASSERT(P2PHASE(size, SPA_MINBLOCKSIZE) == 0);
@@ -436,9 +437,12 @@ zio_create(zio_t *pio, spa_t *spa, uint6
if (bp != NULL) {
+ io_bypass = 0;
+
if (((vd == NULL) || (vd->vdev_parent == NULL)) &&
((type == ZIO_TYPE_WRITE) || (type == ZIO_TYPE_READ)))
- zbio_sync_cache(spa, bp, txg, data, size, type == ZIO_TYPE_WRITE ? BIO_WRITE : BIO_READ);
+ io_bypass = zbio_sync_cache(spa, bp, txg, data, size,
+ type == ZIO_TYPE_WRITE ? BIO_WRITE : BIO_READ);
zio->io_bp = bp;
zio->io_bp_copy = *bp;
@@ -450,6 +454,8 @@ zio_create(zio_t *pio, spa_t *spa, uint6
pipeline |= ZIO_GANG_STAGES;
zio->io_logical = zio;
}
+ if (io_bypass)
+ pipeline = ZIO_INTERLOCK_STAGES;
}
zio->io_spa = spa;
More information about the svn-src-user
mailing list