]> granicus.if.org Git - zfs/commitdiff
It is not necessary to zero struct dbuf_hold_impl_data
authorMatthew Ahrens <mahrens@delphix.com>
Thu, 21 Jul 2016 05:50:26 +0000 (22:50 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 16 Aug 2016 22:27:17 +0000 (15:27 -0700)
Under a workload which makes heavy use of `dbuf_hold()`, I noticed that a
considerable amount of time was spent in `dbuf_hold_impl()`, due to its call to
`kmem_zalloc(sizeof (struct dbuf_hold_impl_data) * DBUF_HOLD_IMPL_MAX_DEPTH)`,
which is around 2KiB.  This structure is used as a stack, to limit the size of
the C stack as dbuf_hold() calls itself recursively.  We make a recursive call
to hold the parent's dbuf when the requested dbuf is not found.  The vast
majority of the time, the parent or grandparent indirect dbuf is cached, so the
number of recursive calls is very low.  However, we initialize this entire
array for every call to dbuf_hold().

To improve performance, this commit changes `dbuf_hold()` to use `kmem_alloc()`
instead of `kmem_zalloc()`.  __dbuf_hold_impl_init is changed to initialize all
members of the struct before they are used.  I observed ~5% performance
improvement on a workload which creates many files.

Signed-off-by: Matthew Ahrens <mahrens@delphix.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #4974

module/zfs/dbuf.c

index af2f20d63b5c835cf0b8e433f662fc2f5171a9bd..1728694ac2e5419e194fa1f0c33a50302a6a0692 100644 (file)
@@ -2472,7 +2472,7 @@ dbuf_hold_impl(dnode_t *dn, uint8_t level, uint64_t blkid,
        struct dbuf_hold_impl_data *dh;
        int error;
 
-       dh = kmem_zalloc(sizeof (struct dbuf_hold_impl_data) *
+       dh = kmem_alloc(sizeof (struct dbuf_hold_impl_data) *
            DBUF_HOLD_IMPL_MAX_DEPTH, KM_SLEEP);
        __dbuf_hold_impl_init(dh, dn, level, blkid, fail_sparse,
                fail_uncached, tag, dbp, 0);
@@ -2500,6 +2500,14 @@ __dbuf_hold_impl_init(struct dbuf_hold_impl_data *dh,
 
        dh->dh_tag = tag;
        dh->dh_dbp = dbp;
+
+       dh->dh_db = NULL;
+       dh->dh_parent = NULL;
+       dh->dh_bp = NULL;
+       dh->dh_err = 0;
+       dh->dh_dr = NULL;
+       dh->dh_type = 0;
+
        dh->dh_depth = depth;
 }