summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorMatthew Ahrens <mahrens@delphix.com>2013-07-03 08:13:38 -0800
committerChristopher Siden <chris.siden@delphix.com>2013-07-03 09:13:38 -0700
commit9cb154a3c9f170904dce9bad5bd5a7d256b922a4 (patch)
tree8a2349eb87a38ce4cce2ad60633ebac97f76a01a /usr
parentef3b9e2fd29bbac9dc0e750d67355287620587a5 (diff)
downloadillumos-joyent-9cb154a3c9f170904dce9bad5bd5a7d256b922a4.tar.gz
3836 zio_free() can be processed immediately in the common case
Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Adam Leventhal <ahl@delphix.com> Approved by: Dan McDonald <danmcd@nexenta.com>
Diffstat (limited to 'usr')
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zio_impl.h5
-rw-r--r--usr/src/uts/common/fs/zfs/zio.c27
2 files changed, 27 insertions, 5 deletions
diff --git a/usr/src/uts/common/fs/zfs/sys/zio_impl.h b/usr/src/uts/common/fs/zfs/sys/zio_impl.h
index 787079d2c9..08f820103e 100644
--- a/usr/src/uts/common/fs/zfs/sys/zio_impl.h
+++ b/usr/src/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)
#define ZIO_DDT_FREE_PIPELINE \
diff --git a/usr/src/uts/common/fs/zfs/zio.c b/usr/src/uts/common/fs/zfs/zio.c
index 7361dcc764..db4807df35 100644
--- a/usr/src/uts/common/fs/zfs/zio.c
+++ b/usr/src/uts/common/fs/zfs/zio.c
@@ -698,7 +698,20 @@ 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, 0)));
+ }
}
zio_t *
@@ -706,6 +719,7 @@ zio_free_sync(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp,
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);
@@ -717,9 +731,18 @@ 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, BP_GET_PSIZE(bp),
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);
}