]> granicus.if.org Git - zfs/commitdiff
Illumos 5694 - traverse_prefetcher does not prefetch enough
authorGeorge Wilson <george.wilson@delphix.com>
Fri, 27 Mar 2015 04:31:52 +0000 (15:31 +1100)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 27 Mar 2015 22:02:50 +0000 (15:02 -0700)
5694 traverse_prefetcher does not prefetch enough
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Alex Reece <alex@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Bayard Bell <buffer.g.overflow@gmail.com>
Approved by: Garrett D'Amore <garrett@damore.org>

References:
  https://www.illumos.org/issues/5694
  https://github.com/illumos/illumos-gate/commit/34d7ce05

Ported-by: Chris Dunlop <chris@onthe.net.au>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #3230

man/man5/zfs-module-parameters.5
module/zfs/dmu_traverse.c

index 9a3e2149ae80d282d86185e6381ccd74d1080a00..783d3532ea8d6e5dfd043ef4d650381821058b01 100644 (file)
@@ -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
index a8481aee61ee419543086aea8a8cb2f1610e3576..9280a89b2f850675acdb997a9ef556ee2ec9b4b9 100644 (file)
 #include <sys/callb.h>
 #include <sys/zfeature.h>
 
-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