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

From: Sergey Senozhatsky

Date: Sun Nov 01 2026 - 18:47:57 EST


Adding Chris for visibility

On (26/10/29 11:26), Sergey Senozhatsky wrote:
> 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?

[..]

> ---
>
> 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)
> {