Date: Sat, 12 Dec 2009 23:41:15 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r200455 - in user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys Message-ID: <200912122341.nBCNfFsI067305@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200912122341.nBCNfFsI067305>