From b738bc5a0f8ccd0281ed06831c34fbe31d2b2138 Mon Sep 17 00:00:00 2001 From: George Wilson Date: Fri, 27 Mar 2015 15:31:52 +1100 Subject: [PATCH] Illumos 5694 - traverse_prefetcher does not prefetch enough 5694 traverse_prefetcher does not prefetch enough Reviewed by: Matthew Ahrens Reviewed by: Alex Reece Reviewed by: Christopher Siden Reviewed by: Josef 'Jeff' Sipek Reviewed by: Bayard Bell Approved by: Garrett D'Amore References: https://www.illumos.org/issues/5694 https://github.com/illumos/illumos-gate/commit/34d7ce05 Ported-by: Chris Dunlop Signed-off-by: Brian Behlendorf Closes #3230 --- man/man5/zfs-module-parameters.5 | 4 ++-- module/zfs/dmu_traverse.c | 23 +++++++++++------------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/man/man5/zfs-module-parameters.5 b/man/man5/zfs-module-parameters.5 index 9a3e2149a..783d3532e 100644 --- a/man/man5/zfs-module-parameters.5 +++ b/man/man5/zfs-module-parameters.5 @@ -1058,10 +1058,10 @@ Use \fB1\fR for yes (default) and \fB0\fR to disable. .sp .ne 2 .na -\fBzfs_pd_blks_max\fR (int) +\fBzfs_pd_bytes_max\fR (int) .ad .RS 12n -Max number of blocks to prefetch +The number of bytes which should be prefetched. .sp Default value: \fB100\fR. .RE diff --git a/module/zfs/dmu_traverse.c b/module/zfs/dmu_traverse.c index a8481aee6..9280a89b2 100644 --- a/module/zfs/dmu_traverse.c +++ b/module/zfs/dmu_traverse.c @@ -38,13 +38,12 @@ #include #include -int zfs_pd_blks_max = 100; +int32_t zfs_pd_bytes_max = 50 * 1024 * 1024; /* 50MB */ typedef struct prefetch_data { kmutex_t pd_mtx; kcondvar_t pd_cv; - int pd_blks_max; - int pd_blks_fetched; + int32_t pd_bytes_fetched; int pd_flags; boolean_t pd_cancel; boolean_t pd_exited; @@ -251,11 +250,12 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp, } if (pd != NULL && !pd->pd_exited && prefetch_needed(pd, bp)) { + uint64_t size = BP_GET_LSIZE(bp); mutex_enter(&pd->pd_mtx); - ASSERT(pd->pd_blks_fetched >= 0); - while (pd->pd_blks_fetched == 0 && !pd->pd_exited) + ASSERT(pd->pd_bytes_fetched >= 0); + while (pd->pd_bytes_fetched < size && !pd->pd_exited) cv_wait(&pd->pd_cv, &pd->pd_mtx); - pd->pd_blks_fetched--; + pd->pd_bytes_fetched -= size; cv_broadcast(&pd->pd_cv); mutex_exit(&pd->pd_mtx); } @@ -452,7 +452,7 @@ traverse_prefetcher(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, prefetch_data_t *pfd = arg; uint32_t aflags = ARC_NOWAIT | ARC_PREFETCH; - ASSERT(pfd->pd_blks_fetched >= 0); + ASSERT(pfd->pd_bytes_fetched >= 0); if (pfd->pd_cancel) return (SET_ERROR(EINTR)); @@ -460,9 +460,9 @@ traverse_prefetcher(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, return (0); mutex_enter(&pfd->pd_mtx); - while (!pfd->pd_cancel && pfd->pd_blks_fetched >= pfd->pd_blks_max) + while (!pfd->pd_cancel && pfd->pd_bytes_fetched >= zfs_pd_bytes_max) cv_wait(&pfd->pd_cv, &pfd->pd_mtx); - pfd->pd_blks_fetched++; + pfd->pd_bytes_fetched += BP_GET_LSIZE(bp); cv_broadcast(&pfd->pd_cv); mutex_exit(&pfd->pd_mtx); @@ -531,7 +531,6 @@ traverse_impl(spa_t *spa, dsl_dataset_t *ds, uint64_t objset, blkptr_t *rootbp, td->td_flags = flags; td->td_paused = B_FALSE; - pd->pd_blks_max = zfs_pd_blks_max; pd->pd_flags = flags; mutex_init(&pd->pd_mtx, NULL, MUTEX_DEFAULT, NULL); cv_init(&pd->pd_cv, NULL, CV_DEFAULT, NULL); @@ -661,6 +660,6 @@ traverse_pool(spa_t *spa, uint64_t txg_start, int flags, EXPORT_SYMBOL(traverse_dataset); EXPORT_SYMBOL(traverse_pool); -module_param(zfs_pd_blks_max, int, 0644); -MODULE_PARM_DESC(zfs_pd_blks_max, "Max number of blocks to prefetch"); +module_param(zfs_pd_bytes_max, int, 0644); +MODULE_PARM_DESC(zfs_pd_bytes_max, "Max number of bytes to prefetch"); #endif