Re: [PATCH bpf-next 1/4] mm/bpf: Add bpf_try_to_free_mem_cgroup_pages kfunc

From: Shakeel Butt

Date: Thu Aug 13 2026 - 14:44:09 EST


Hi Hui,

Please narrow down your CC list, I would suggest to CC only memcg and bpf
folks.

On Fri, Aug 07, 2026 at 03:01:49PM +0800, Hui Zhu wrote:
> From: Hui Zhu <zhuhui@xxxxxxxxxx>

[...]

First of all, good decision to decouple this series from the struct_ops for
memcg as the struct_ops for cgroup series is still in flux and I have different
plans on how memcg struct_ops should look like. We can discuss and collaborate
on how that should look like which satisfies the real use-cases we have instead
of arbitrary or imaginery use-cases.

Others are already discussing the bpf side of things, so let me focus on the
memcg side.

>
> +/**
> + * bpf_try_to_free_mem_cgroup_pages - attempt to reclaim pages from
> + * a memory cgroup
> + * @memcg: the target memory cgroup to reclaim from
> + * @nr_pages: the number of pages to reclaim
> + * @gfp_mask: GFP flags controlling the reclaim behavior
> + * @reclaim_options: bitmask of MEMCG_RECLAIM_* flags to tune
> + * reclaim strategy
> + * @swappiness: swappiness override value, or a sentinel to use
> + * the default
> + *
> + * BPF-facing wrapper around try_to_free_mem_cgroup_pages() that
> + * validates and translates the @swappiness argument before
> + * delegating to the core reclaim path.
> + *
> + * The @swappiness parameter follows these semantics:
> + * - Values in [MIN_SWAPPINESS, SWAPPINESS_ANON_ONLY] are passed
> + * through as an explicit swappiness override.
> + * - Values below MIN_SWAPPINESS are treated as "use the system
> + * default"; the override pointer is set to NULL and the cgroup's
> + * own swappiness setting takes effect.
> + * - Values above SWAPPINESS_ANON_ONLY are rejected as invalid.
> + * - If @reclaim_options does not include MEMCG_RECLAIM_PROACTIVE,
> + * the @swappiness override is ignored entirely by the core
> + * reclaim path and the system default is used regardless.
> + *
> + * Swap usage during reclaim is gated on @reclaim_options: swap is
> + * considered only when MEMCG_RECLAIM_MAY_SWAP is set. Without this
> + * flag, reclaim is restricted to file-backed pages regardless of the
> + * @swappiness value or the cgroup's swappiness setting.
> + *
> + * Return:
> + * The number of pages actually reclaimed on success, or 0
> + * if @swappiness exceeds SWAPPINESS_ANON_ONLY.
> + */
> +__bpf_kfunc unsigned long
> +bpf_try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
> + unsigned long nr_pages,
> + gfp_t gfp_mask,
> + unsigned int reclaim_options,
> + int swappiness)
> +{
> + int *swapiness_ptr;
> +
> + if (swappiness > SWAPPINESS_ANON_ONLY)
> + return 0;
> + else if (swappiness < MIN_SWAPPINESS)
> + swapiness_ptr = NULL;
> + else
> + swapiness_ptr = &swappiness;
> +
> + return try_to_free_mem_cgroup_pages(memcg, nr_pages, gfp_mask,
> + reclaim_options, swapiness_ptr);
> +}

This is just a wrapper on try_to_free_mem_cgroup_pages. We don't want that. At
the moment try_to_free_mem_cgroup_pages is used by limit reclaims (memory and
memsw, high) and proactive reclaim and has become a weird looking interface. We
should not expose it as is to the bpf programs.

Let's go back to the use-case for which you want to expose this interface. Your
cover letter says proactive reclaim. Let's focus on (existing) proactive reclaim
use-case (in future we may want more functionality). Proactive reclaim is done
on a given memcg, amount of memory to reclaim and swappiness.

Let's start with just:
unsigned long bpf_proactive_reclaim(memcg, size);

And if we clearly have a swappiness use-case then let's add one more kfunc:
unsigned long bpf_proactive_reclaim_swappiness(memcg, size, swappiness);

So, my main point is let's drive the kfuncs from the real use-cases.

thanks,
Shakeel