[PATCH 16/21] cache: support gradual expansion

Darrick J. Wong
2025-09-16T00:54:49Z

It's probably not a good idea to expand the cache size by powers of two
beyond some random limit, so let the users figure that out if they want
to.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
lib/support/cache.h | 10 ++++++++++
lib/support/cache.c | 12 ++++++++++--
2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/lib/support/cache.h b/lib/support/cache.h
index 98b2182d49a6e0..ae37945c545f46 100644
--- a/lib/support/cache.h
+++ b/lib/support/cache.h
@@ -66,6 +66,14 @@ typedef int (*cache_node_compare_t)(struct cache_node *, cache_key_t);
typedef unsigned int (*cache_bulk_relse_t)(struct cache *, struct list_head *);
typedef int (*cache_node_get_t)(struct cache *c, struct cache_node *cn);
typedef void (*cache_node_put_t)(struct cache *c, struct cache_node *cn);
+typedef unsigned int (*cache_node_resize_t)(const struct cache *c,
+ unsigned int curr_size);
+
+static inline unsigned int cache_gradual_resize(const struct cache *cache,
+ unsigned int curr_size)
+{
+ return curr_size * 5 / 4;
+}

struct cache_operations {
cache_node_hash_t hash;
@@ -76,6 +84,7 @@ struct cache_operations {
cache_bulk_relse_t bulkrelse; /* optional */
cache_node_get_t get; /* optional */
cache_node_put_t put; /* optional */
+ cache_node_resize_t resize; /* optional */
};

struct cache_hash {
@@ -113,6 +122,7 @@ struct cache {
cache_bulk_relse_t bulkrelse; /* bulk release routine */
cache_node_get_t get; /* prepare cache node after get */
cache_node_put_t put; /* prepare to put cache node */
+ cache_node_resize_t resize; /* compute new maxcount */
unsigned int c_hashsize; /* hash bucket count */
unsigned int c_hashshift; /* hash key shift */
struct cache_hash *c_hash; /* hash table buckets */
diff --git a/lib/support/cache.c b/lib/support/cache.c
index 9da6c59b3b6391..dbaddc1bd36d3d 100644
--- a/lib/support/cache.c
+++ b/lib/support/cache.c
@@ -62,6 +62,7 @@ cache_init(
cache_operations->bulkrelse : cache_generic_bulkrelse;
cache->get = cache_operations->get;
cache->put = cache_operations->put;
+ cache->resize = cache_operations->resize;
pthread_mutex_init(&cache->c_mutex, NULL);

for (i = 0; i <= CACHE_DIRTY_PRIORITY; i++) {
@@ -90,11 +91,18 @@ static void
cache_expand(
struct cache * cache)
{
+ unsigned int new_size = 0;
+
pthread_mutex_lock(&cache->c_mutex);
+ if (cache->resize)
+ new_size = cache->resize(cache, cache->c_maxcount);
+ if (new_size <= cache->c_maxcount)
+ new_size = cache->c_maxcount * 2;
#ifdef CACHE_DEBUG
- fprintf(stderr, "doubling cache size to %d\n", 2 * cache->c_maxcount);
+ fprintf(stderr, "increasing cache max size from %u to %u\n",
+ cache->c_maxcount, new_size);
#endif
- cache->c_maxcount *= 2;
+ cache->c_maxcount = new_size;
pthread_mutex_unlock(&cache->c_mutex);
}