From: Darrick J. Wong <djwong@xxxxxxxxxx> If a buffer is hot enough to survive more than 50 access without being reclaimed, bump its priority to the next MRU so it sticks around longer. Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- lib/support/cache.h | 1 + lib/support/cache.c | 16 ++++++++++++++++ lib/support/iocache.c | 9 +++++++++ 3 files changed, 26 insertions(+) diff --git a/lib/support/cache.h b/lib/support/cache.h index f482948a3b6331..5a8e19f5d18e78 100644 --- a/lib/support/cache.h +++ b/lib/support/cache.h @@ -173,5 +173,6 @@ int cache_node_purge(struct cache *, cache_key_t, struct cache_node *); void cache_report(FILE *fp, const char *, struct cache *); int cache_overflowed(struct cache *); struct cache_node *cache_node_grab(struct cache *cache, struct cache_node *node); +void cache_node_bump_priority(struct cache *cache, struct cache_node *node); #endif /* __CACHE_H__ */ diff --git a/lib/support/cache.c b/lib/support/cache.c index 7e1ddc3cc8788d..34df5cb51cd5e4 100644 --- a/lib/support/cache.c +++ b/lib/support/cache.c @@ -649,6 +649,22 @@ cache_node_put( cache_shrink(cache); } +/* Bump the priority of a cache node. Caller must hold cn_mutex. */ +void +cache_node_bump_priority( + struct cache *cache, + struct cache_node *node) +{ + int *priop; + + if (node->cn_priority == CACHE_DIRTY_PRIORITY) + priop = &node->cn_old_priority; + else + priop = &node->cn_priority; + if (*priop < CACHE_MAX_PRIORITY) + (*priop)++; +} + void cache_node_set_priority( struct cache * cache, diff --git a/lib/support/iocache.c b/lib/support/iocache.c index ab879e85d18f2a..92d88331bfa54d 100644 --- a/lib/support/iocache.c +++ b/lib/support/iocache.c @@ -56,6 +56,7 @@ struct iocache_buf { blk64_t block; void *buf; errcode_t write_error; + uint8_t access; unsigned int uptodate:1; unsigned int dirty:1; }; @@ -552,6 +553,10 @@ static errcode_t iocache_read_blk64(io_channel channel, } if (ubuf->uptodate) memcpy(buf, ubuf->buf, channel->block_size); + if (++ubuf->access > 50) { + cache_node_bump_priority(&data->cache, node); + ubuf->access = 0; + } iocache_buf_unlock(ubuf); cache_node_put(&data->cache, node); if (retval) @@ -613,6 +618,10 @@ static errcode_t iocache_write_blk64(io_channel channel, ubuf->uptodate ? CACHE_HIT : CACHE_MISS); ubuf->dirty = 1; ubuf->uptodate = 1; + if (++ubuf->access > 50) { + cache_node_bump_priority(&data->cache, node); + ubuf->access = 0; + } iocache_buf_unlock(ubuf); cache_node_put(&data->cache, node); }