summaryrefslogtreecommitdiffstats
path: root/module/zfs/dbuf.c
diff options
context:
space:
mode:
authorMatthew Ahrens <[email protected]>2016-07-20 22:50:26 -0700
committerBrian Behlendorf <[email protected]>2016-08-16 15:27:17 -0700
commitd9eea113f8b8988a8ec4f9c73b717c7311322348 (patch)
tree6657cf547fb9cc44626433d319b7f550997aa8a4 /module/zfs/dbuf.c
parentf0c26069bdf4ec675c840f0932fcfe7d4036d06f (diff)
It is not necessary to zero struct dbuf_hold_impl_data
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 <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #4974
Diffstat (limited to 'module/zfs/dbuf.c')
-rw-r--r--module/zfs/dbuf.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c
index af2f20d63..1728694ac 100644
--- a/module/zfs/dbuf.c
+++ b/module/zfs/dbuf.c
@@ -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;
}