summaryrefslogtreecommitdiffstats
path: root/include/sys
diff options
context:
space:
mode:
authorAlexander Motin <[email protected]>2022-05-25 13:12:52 -0400
committerBrian Behlendorf <[email protected]>2022-07-26 10:10:37 -0700
commit884364ea85423fdd431f6269c42228ab74c4846d (patch)
tree683f4035b0025c9631990fac7ac169b83a43f1c7 /include/sys
parent6e1e90d64cf26d66ff0b5a50fa294be162356ada (diff)
More speculative prefetcher improvements
- Make prefetch distance adaptive: up to 4MB prefetch doubles for every, hit same as before, but after that it grows by 1/8 every time the prefetch read does not complete in time to satisfy the demand. My tests show that 4MB is sufficient for wide NVMe pool to saturate single reader thread at 2.5GB/s, while new 64MB maximum allows the same thread to reach 1.5GB/s on wide HDD pool. Further distance increase may increase speed even more, but less dramatic and with higher latency. - Allow early reuse of inactive prefetch streams: streams that never saw hits can be reused immediately if there is a demand, while others can be reused after 1s of inactivity, starting with the oldest. After 2s of inactivity streams are deleted to free resources same as before. This allows by several times increase strided read performance on HDD pool in presence of simultaneous random reads, previously filling the zfetch_max_streams limit for seconds and so blocking most of prefetch. - Always issue intermediate indirect block reads with SYNC priority. Each of those reads if delayed for longer may delay up to 1024 other block prefetches, that may be not good for wide pools. Reviewed-by: Allan Jude <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Alexander Motin <[email protected]> Sponsored-By: iXsystems, Inc. Closes #13452
Diffstat (limited to 'include/sys')
-rw-r--r--include/sys/dbuf.h2
-rw-r--r--include/sys/dmu_zfetch.h16
2 files changed, 8 insertions, 10 deletions
diff --git a/include/sys/dbuf.h b/include/sys/dbuf.h
index e7289c0fe..93d80066b 100644
--- a/include/sys/dbuf.h
+++ b/include/sys/dbuf.h
@@ -329,7 +329,7 @@ typedef struct dbuf_hash_table {
krwlock_t hash_rwlocks[DBUF_RWLOCKS] ____cacheline_aligned;
} dbuf_hash_table_t;
-typedef void (*dbuf_prefetch_fn)(void *, boolean_t);
+typedef void (*dbuf_prefetch_fn)(void *, uint64_t, uint64_t, boolean_t);
uint64_t dbuf_whichblock(const struct dnode *di, const int64_t level,
const uint64_t offset);
diff --git a/include/sys/dmu_zfetch.h b/include/sys/dmu_zfetch.h
index 4c220b0c7..cd1b79eb8 100644
--- a/include/sys/dmu_zfetch.h
+++ b/include/sys/dmu_zfetch.h
@@ -49,20 +49,18 @@ typedef struct zfetch {
typedef struct zstream {
uint64_t zs_blkid; /* expect next access at this blkid */
- uint64_t zs_pf_blkid1; /* first block to prefetch */
- uint64_t zs_pf_blkid; /* block to prefetch up to */
-
- /*
- * We will next prefetch the L1 indirect block of this level-0
- * block id.
- */
- uint64_t zs_ipf_blkid1; /* first block to prefetch */
- uint64_t zs_ipf_blkid; /* block to prefetch up to */
+ unsigned int zs_pf_dist; /* data prefetch distance in bytes */
+ unsigned int zs_ipf_dist; /* L1 prefetch distance in bytes */
+ uint64_t zs_pf_start; /* first data block to prefetch */
+ uint64_t zs_pf_end; /* data block to prefetch up to */
+ uint64_t zs_ipf_start; /* first data block to prefetch L1 */
+ uint64_t zs_ipf_end; /* data block to prefetch L1 up to */
list_node_t zs_node; /* link for zf_stream */
hrtime_t zs_atime; /* time last prefetch issued */
zfetch_t *zs_fetch; /* parent fetch */
boolean_t zs_missed; /* stream saw cache misses */
+ boolean_t zs_more; /* need more distant prefetch */
zfs_refcount_t zs_callers; /* number of pending callers */
/*
* Number of stream references: dnode, callers and pending blocks.