diff options
author | mm <mm@FreeBSD.org> | 2013-07-05 21:29:59 +0000 |
---|---|---|
committer | mm <mm@FreeBSD.org> | 2013-07-05 21:29:59 +0000 |
commit | be7444451060bb6bbf361f251d66c2a5c689d37f (patch) | |
tree | 1fbc4ca207bba2a6bcc0d1f7410ffcdbf6bc3b13 /sys/cddl | |
parent | 0a786bb76e3daf688bbd1393512c2540f1ccd851 (diff) | |
download | FreeBSD-src-be7444451060bb6bbf361f251d66c2a5c689d37f.zip FreeBSD-src-be7444451060bb6bbf361f251d66c2a5c689d37f.tar.gz |
MFV r252839:
Quoting illumos issue #3836:
Currently zio_free() always puts the zio on a list for subsequent
processing by zio_free_sync(). This is only necessary for frees that
might need to issue reads (gang and dedup blocks).
By processing the majority of the frees as we encounter them, we reduce
the amount of time that the spa_sync() thread spends burning CPU and
not doing any i/o, thus increasing the overall write throughput of the
system.
Illumos ZFS issues:
3836 zio_free() can be processed immediately in the common case
MFC after: 1 week
Diffstat (limited to 'sys/cddl')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_impl.h | 5 | ||||
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c | 27 |
2 files changed, 27 insertions, 5 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_impl.h index aa44744..6695c2f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_impl.h @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #ifndef _ZIO_IMPL_H @@ -38,7 +38,7 @@ extern "C" { #endif /* - * XXX -- Describe ZFS I/O pipleine here. Fill in as needed. + * XXX -- Describe ZFS I/O pipeline here. Fill in as needed. * * The ZFS I/O pipeline is comprised of various stages which are defined * in the zio_stage enum below. The individual stages are used to construct @@ -213,7 +213,6 @@ enum zio_stage { #define ZIO_FREE_PIPELINE \ (ZIO_INTERLOCK_STAGES | \ ZIO_STAGE_FREE_BP_INIT | \ - ZIO_STAGE_ISSUE_ASYNC | \ ZIO_STAGE_DVA_FREE | \ ZIO_STAGE_VDEV_IO_START | \ ZIO_STAGE_VDEV_IO_ASSESS) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c index c04930f..62dfe92 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -763,7 +763,21 @@ void zio_free(spa_t *spa, uint64_t txg, const blkptr_t *bp) { metaslab_check_free(spa, bp); - bplist_append(&spa->spa_free_bplist[txg & TXG_MASK], bp); + + /* + * Frees that are for the currently-syncing txg, are not going to be + * deferred, and which will not need to do a read (i.e. not GANG or + * DEDUP), can be processed immediately. Otherwise, put them on the + * in-memory list for later processing. + */ + if (BP_IS_GANG(bp) || BP_GET_DEDUP(bp) || + txg != spa->spa_syncing_txg || + spa_sync_pass(spa) >= zfs_sync_pass_deferred_free) { + bplist_append(&spa->spa_free_bplist[txg & TXG_MASK], bp); + } else { + VERIFY0(zio_wait(zio_free_sync(NULL, spa, txg, bp, + BP_GET_PSIZE(bp), 0))); + } } zio_t * @@ -771,6 +785,7 @@ zio_free_sync(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp, uint64_t size, enum zio_flag flags) { zio_t *zio; + enum zio_stage stage = ZIO_FREE_PIPELINE; dprintf_bp(bp, "freeing in txg %llu, pass %u", (longlong_t)txg, spa->spa_sync_pass); @@ -782,9 +797,17 @@ zio_free_sync(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp, metaslab_check_free(spa, bp); arc_freed(spa, bp); + /* + * GANG and DEDUP blocks can induce a read (for the gang block header, + * or the DDT), so issue them asynchronously so that this thread is + * not tied up. + */ + if (BP_IS_GANG(bp) || BP_GET_DEDUP(bp)) + stage |= ZIO_STAGE_ISSUE_ASYNC; + zio = zio_create(pio, spa, txg, bp, NULL, size, NULL, NULL, ZIO_TYPE_FREE, ZIO_PRIORITY_FREE, flags, - NULL, 0, NULL, ZIO_STAGE_OPEN, ZIO_FREE_PIPELINE); + NULL, 0, NULL, ZIO_STAGE_OPEN, stage); return (zio); } |