[PATCH 3/6] iocache: bump buffer mru priority every 50 accesses

Darrick J. Wong
2025-08-21T01:24:03Z

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@kernel.org>
---
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);
}