Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware

From: Sergey Senozhatsky

Date: Wed Oct 28 2026 - 22:29:34 EST


On (26/08/07 09:25), Nhat Pham wrote:
> Hmm we'd need to collect more data in our workloads to determine, but
> if we can compute compactable ratio (freeable_pages / total_pages) on
> a per size class basis, can we just skip the size class whose ratio is
> too bad? Would that at least cut down on the vast majority of
> fruitless memcpys and lock acquisitions etc?

To calculate those we need to tool pool/class locks. But technically
possible. Not sure, how would be determine the threshold tho.

On the other alternative is quite simple. We can make it
"default ZSWAP", for example.

---

diff --git a/mm/Kconfig b/mm/Kconfig
index afff1b25b543..72542946bc53 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -157,6 +157,17 @@ config ZSMALLOC_CHAIN_SIZE

For more information, see zsmalloc documentation.

+config ZSMALLOC_SHRINKER
+ bool "Enable zsmalloc pool shrinker"
+ default y
+ help
+ This option enables the zsmalloc pool shrinker, which allows
+ the zsmalloc pool to be shrunk when the system is under memory
+ pressure. The shrinker will attempt to free up memory by
+ compacting zspages and releasing empty zspages back to the system.
+
+ If unsure, say N.
+
endmenu

menu "Slab allocator options"
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 7ef80e0da626..e0d7ab9142bb 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -276,8 +276,10 @@ struct zs_pool {

struct zs_pool_stats stats;

+#ifdef CONFIG_ZSMALLOC_SHRINKER
/* Compact classes */
struct shrinker *shrinker;
+#endif

#ifdef CONFIG_ZSMALLOC_STAT
struct dentry *stat_dentry;
@@ -2050,8 +2052,9 @@ void zs_pool_stats(struct zs_pool *pool, struct zs_pool_stats *stats)
}
EXPORT_SYMBOL_GPL(zs_pool_stats);

+#ifdef CONFIG_ZSMALLOC_SHRINKER
static unsigned long zs_shrinker_scan(struct shrinker *shrinker,
- struct shrink_control *sc)
+ struct shrink_control *sc)
{
unsigned long pages_freed;
struct zs_pool *pool = shrinker->private_data;
@@ -2067,7 +2070,7 @@ static unsigned long zs_shrinker_scan(struct shrinker *shrinker,
}

static unsigned long zs_shrinker_count(struct shrinker *shrinker,
- struct shrink_control *sc)
+ struct shrink_control *sc)
{
int i;
struct size_class *class;
@@ -2105,6 +2108,10 @@ static int zs_register_shrinker(struct zs_pool *pool)

return 0;
}
+#else
+static void zs_unregister_shrinker(struct zs_pool *pool) { }
+static int zs_register_shrinker(struct zs_pool *pool) { return 0; }
+#endif

static int calculate_zspage_chain_size(int class_size)
{