> diff --git a/mm/bpf_memcontrol.c b/mm/bpf_memcontrol.c
> index 716df49d7647..92272f9a5825 100644
> --- a/mm/bpf_memcontrol.c
> +++ b/mm/bpf_memcontrol.c
[ ... ]
> @@ -159,6 +160,97 @@ __bpf_kfunc void bpf_mem_cgroup_flush_stats(struct mem_cgroup *memcg)
> mem_cgroup_flush_stats(memcg);
> }
>
> +/**
> + * bpf_proactive_reclaim - proactively reclaim memory from a memory
> + * cgroup
> + * @memcg: the target memory cgroup to reclaim from
> + * @size: the amount of memory to reclaim, in bytes
> + *
> + * Trigger one proactive reclaim pass on @memcg, similar to a write to
> + * the memory.reclaim cgroup file: pages are reclaimed according to the
> + * cgroup's own swappiness setting and swap is allowed. Note that,
> + * unlike memory.reclaim, this does not retry until @size is reached;
> + * callers can invoke it again if needed.
> + *
> + * Return:
> + * The number of pages actually reclaimed, or 0 if @size is smaller
> + * than a page or the calling task is already in a reclaim/freeing
> + * context (PF_MEMALLOC).
> + */
> +__bpf_kfunc unsigned long bpf_proactive_reclaim(struct mem_cgroup *memcg,
> + unsigned long size)
> +{
> + unsigned long nr_pages = size / PAGE_SIZE;
> +
> + if (!nr_pages || unlikely(bpf_in_reclaim_context()))
> + return 0;
> +
> + return try_to_free_mem_cgroup_pages(memcg, nr_pages, GFP_KERNEL,
> + MEMCG_RECLAIM_MAY_SWAP |
> + MEMCG_RECLAIM_PROACTIVE, NULL);
> +}
> +
> +/**
> + * bpf_proactive_reclaim_swappiness - proactively reclaim memory from a
> + * memory cgroup with an explicit
> + * swappiness
> + * @memcg: the target memory cgroup to reclaim from
> + * @size: the amount of memory to reclaim, in bytes
> + * @swappiness: swappiness override for this reclaim pass
> + *
> + * Same as bpf_proactive_reclaim(), except that the anon/file reclaim
> + * balance is controlled by @swappiness instead of the cgroup's
> + * swappiness setting. Valid values are [MIN_SWAPPINESS, MAX_SWAPPINESS]
> + * and SWAPPINESS_ANON_ONLY, which restricts reclaim to anon folios.
> + *
> + * Return:
> + * The number of pages actually reclaimed, or 0 if @size is smaller
> + * than a page, @swappiness is out of range, or the calling task is
> + * already in a reclaim/freeing context (PF_MEMALLOC).
> + */
> +__bpf_kfunc unsigned long
> +bpf_proactive_reclaim_swappiness(struct mem_cgroup *memcg, unsigned long size,
> + int swappiness)
> +{
> + unsigned long nr_pages = size / PAGE_SIZE;
> +
> + if (!nr_pages || swappiness < MIN_SWAPPINESS ||
> + swappiness > SWAPPINESS_ANON_ONLY ||
> + unlikely(bpf_in_reclaim_context()))
> + return 0;
> +
> + return try_to_free_mem_cgroup_pages(memcg, nr_pages, GFP_KERNEL,
> + MEMCG_RECLAIM_MAY_SWAP |
> + MEMCG_RECLAIM_PROACTIVE,
> + &swappiness);
> +}
This isn't a bug, but these two kfuncs are nearly identical apart from the
swappiness range check and passing '&swappiness' vs 'NULL' to
try_to_free_mem_cgroup_pages(). Both compute 'nr_pages = size /
PAGE_SIZE', both apply the same '!nr_pages ||
unlikely(bpf_in_reclaim_context())' guard, and both use identical
'GFP_KERNEL, MEMCG_RECLAIM_MAY_SWAP | MEMCG_RECLAIM_PROACTIVE' arguments.
Would a shared static helper taking an 'int *swappiness' parameter (the
shape try_to_free_mem_cgroup_pages() already accepts) keep the guard logic
and reclaim flags in one place?
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/32118218829
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.