Re: [PATCH v3 3/4] mm/zswap: Add per-memcg stat for proactive writeback

From: Nhat Pham

Date: Fri May 29 2026 - 16:11:47 EST


On Tue, May 26, 2026 at 4:46 AM Hao Jia <jiahao.kernel@xxxxxxxxx> wrote:
>
> From: Hao Jia <jiahao1@xxxxxxxxxxx>
>
> Currently, zswap writeback can be triggered by either the pool limit
> being hit or by the proactive writeback mechanism. However, the
> existing 'zswpwb' metric in memory.stat and /proc/vmstat counts all
> written back pages, making it difficult to distinguish between pages
> written back due to the pool limit and those written back proactively.
>
> Add a new statistic 'zswpwb_proactive' to memory.stat and /proc/vmstat.
> This counter tracks the number of pages written back due to proactive
> writeback. This allows users to better monitor and tune the proactive
> writeback mechanism.
>
> Signed-off-by: Hao Jia <jiahao1@xxxxxxxxxxx>
> ---
> Documentation/admin-guide/cgroup-v2.rst | 4 +++
> include/linux/vm_event_item.h | 1 +
> mm/memcontrol.c | 1 +
> mm/vmstat.c | 1 +
> mm/zswap.c | 41 ++++++++++++++++++-------
> 5 files changed, 37 insertions(+), 11 deletions(-)
>
> diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
> index 6564abf0dec5..7d65aef83f7b 100644
> --- a/Documentation/admin-guide/cgroup-v2.rst
> +++ b/Documentation/admin-guide/cgroup-v2.rst
> @@ -1748,6 +1748,10 @@ The following nested keys are defined.
> zswpwb
> Number of pages written from zswap to swap.
>
> + zswpwb_proactive
> + Number of pages written from zswap to swap by proactive
> + writeback. This is a subset of zswpwb.
> +

nit: I think this is specifically the zswap_writeback_only mode right?

Technically, normal proactive reclaim (memory.reclaim) can also hit zswap :)

Maybe some clarification here?

> zswap_incomp
> Number of incompressible pages currently stored in zswap
> without compression. These pages could not be compressed to
> diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
> index 03fe95f5a020..7a5bee0a20b6 100644
> --- a/include/linux/vm_event_item.h
> +++ b/include/linux/vm_event_item.h
> @@ -138,6 +138,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
> ZSWPIN,
> ZSWPOUT,
> ZSWPWB,
> + ZSWPWB_PROACTIVE,
> #endif
> #ifdef CONFIG_X86
> DIRECT_MAP_LEVEL2_SPLIT,
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index e205e5de193d..7648b3fd940e 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -571,6 +571,7 @@ static const unsigned int memcg_vm_event_stat[] = {
> ZSWPIN,
> ZSWPOUT,
> ZSWPWB,
> + ZSWPWB_PROACTIVE,
> #endif
> #ifdef CONFIG_TRANSPARENT_HUGEPAGE
> THP_FAULT_ALLOC,
> diff --git a/mm/vmstat.c b/mm/vmstat.c
> index f534972f517d..66fd06d1bb01 100644
> --- a/mm/vmstat.c
> +++ b/mm/vmstat.c
> @@ -1452,6 +1452,7 @@ const char * const vmstat_text[] = {
> [I(ZSWPIN)] = "zswpin",
> [I(ZSWPOUT)] = "zswpout",
> [I(ZSWPWB)] = "zswpwb",
> + [I(ZSWPWB_PROACTIVE)] = "zswpwb_proactive",
> #endif
> #ifdef CONFIG_X86
> [I(DIRECT_MAP_LEVEL2_SPLIT)] = "direct_map_level2_splits",
> diff --git a/mm/zswap.c b/mm/zswap.c
> index 7bcbf788f634..b45d094f532a 100644
> --- a/mm/zswap.c
> +++ b/mm/zswap.c
> @@ -160,6 +160,11 @@ struct zswap_pool {
> char tfm_name[CRYPTO_MAX_ALG_NAME];
> };
>
> +struct zswap_shrink_walk_arg {
> + bool proactive;
> + bool encountered_page_in_swapcache;
> +};
> +
> /* Global LRU lists shared by all zswap pools. */
> static struct list_lru zswap_list_lru;
>
> @@ -1042,7 +1047,8 @@ static bool zswap_decompress(struct zswap_entry *entry, struct folio *folio)
> * freed.
> */
> static int zswap_writeback_entry(struct zswap_entry *entry,
> - swp_entry_t swpentry)
> + swp_entry_t swpentry,
> + bool proactive)
> {
> struct xarray *tree;
> pgoff_t offset = swp_offset(swpentry);
> @@ -1097,6 +1103,12 @@ static int zswap_writeback_entry(struct zswap_entry *entry,
> if (entry->objcg)
> count_objcg_events(entry->objcg, ZSWPWB, 1);
>
> + if (proactive) {
> + count_vm_event(ZSWPWB_PROACTIVE);
> + if (entry->objcg)
> + count_objcg_events(entry->objcg, ZSWPWB_PROACTIVE, 1);
> + }
> +

With the above clarification, the rest LGTM.

Reviewed-by: Nhat Pham <nphamcs@xxxxxxxxx>