Re: [PATCH v2 3/3] mm: move reclaim-internal declarations out of swap.h
From: David Hildenbrand (Arm)
Date: Mon Jun 01 2026 - 11:05:15 EST
On 5/31/26 11:50, Jianyue Wu wrote:
> Keep include/linux/swap.h focused on swap-facing interfaces by moving
> MM-internal reclaim and workingset declarations into mm/internal.h.
>
> Leave the small set of LRU helper declarations that are used outside mm/
> in swap.h so this cleanup does not need a new public header under
> include/linux/.
>
> Signed-off-by: Jianyue Wu <wujianyue000@xxxxxxxxx>
> ---
> include/linux/swap.h | 75 +++++-----------------------------------------------
> mm/internal.h | 66 +++++++++++++++++++++++++++++++++++++++++++++
> mm/memfd.c | 1 +
> 3 files changed, 73 insertions(+), 69 deletions(-)
>
> diff --git a/include/linux/swap.h b/include/linux/swap.h
> index c36f72877e8b..1ef6ae7b2db7 100644
> --- a/include/linux/swap.h
> +++ b/include/linux/swap.h
> @@ -292,39 +292,17 @@ static inline swp_entry_t page_swap_entry(struct page *page)
> return entry;
> }
>
> -/* linux/mm/workingset.c */
> -bool workingset_test_recent(void *shadow, bool file, bool *workingset,
> - bool flush);
> -void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages);
> -void *workingset_eviction(struct folio *folio, struct mem_cgroup *target_memcg);
> -void workingset_refault(struct folio *folio, void *shadow);
> -void workingset_activation(struct folio *folio);
> -
> /* linux/mm/page_alloc.c */
> extern unsigned long totalreserve_pages;
>
> /* Definition of global_zone_page_state not available yet */
> #define nr_free_pages() global_zone_page_state(NR_FREE_PAGES)
>
> -
> -/* linux/mm/swap.c */
> -void lru_note_cost_unlock_irq(struct lruvec *lruvec, bool file,
> - unsigned int nr_io, unsigned int nr_rotated);
> -void lru_note_cost_refault(struct folio *);
> -void folio_add_lru(struct folio *);
> -void folio_add_lru_vma(struct folio *, struct vm_area_struct *);
> -void mark_page_accessed(struct page *);
> -void folio_mark_accessed(struct folio *);
> -
> -static inline bool folio_may_be_lru_cached(struct folio *folio)
> -{
> - /*
> - * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting.
> - * Holding small numbers of low-order mTHP folios in per-CPU LRU cache
> - * will be sensible, but nobody has implemented and tested that yet.
> - */
> - return !folio_test_large(folio);
> -}
> +/* Generic folio LRU helpers used outside mm/. */
> +void folio_add_lru(struct folio *folio);
> +void mark_page_accessed(struct page *page);
> +void folio_mark_accessed(struct folio *folio);
> +void lru_add_drain_all(void);
>
> extern atomic_t lru_disable_count;
>
> @@ -333,43 +311,7 @@ static inline bool lru_cache_disabled(void)
> return atomic_read(&lru_disable_count);
> }
>
> -static inline void lru_cache_enable(void)
> -{
> - atomic_dec(&lru_disable_count);
> -}
> -
> -extern void lru_cache_disable(void);
> -extern void lru_add_drain(void);
> -extern void lru_add_drain_cpu(int cpu);
> -extern void lru_add_drain_cpu_zone(struct zone *zone);
> -extern void lru_add_drain_all(void);
> -void folio_deactivate(struct folio *folio);
> -void folio_mark_lazyfree(struct folio *folio);
> -extern void swap_readahead_setup(void);
> -
> /* linux/mm/vmscan.c */
> -extern unsigned long zone_reclaimable_pages(struct zone *zone);
> -extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
> - gfp_t gfp_mask, nodemask_t *mask);
> -unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone_idx);
> -
> -#define MEMCG_RECLAIM_MAY_SWAP (1 << 1)
> -#define MEMCG_RECLAIM_PROACTIVE (1 << 2)
> -#define MIN_SWAPPINESS 0
> -#define MAX_SWAPPINESS 200
> -
> -/* Just reclaim from anon folios in proactive memory reclaim */
> -#define SWAPPINESS_ANON_ONLY (MAX_SWAPPINESS + 1)
> -
> -extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
> - unsigned long nr_pages,
> - gfp_t gfp_mask,
> - unsigned int reclaim_options,
> - int *swappiness);
> -extern unsigned long mem_cgroup_shrink_node(struct mem_cgroup *mem,
> - gfp_t gfp_mask, bool noswap,
> - pg_data_t *pgdat,
> - unsigned long *nr_scanned);
> extern unsigned long shrink_all_memory(unsigned long nr_pages);
> extern int vm_swappiness;
> long remove_mapping(struct address_space *mapping, struct folio *folio);
> @@ -390,11 +332,6 @@ static inline void reclaim_unregister_node(struct node *node)
> }
> #endif /* CONFIG_SYSFS && CONFIG_NUMA */
>
> -#ifdef CONFIG_NUMA
> -extern int sysctl_min_unmapped_ratio;
> -extern int sysctl_min_slab_ratio;
> -#endif
> -
> void check_move_unevictable_folios(struct folio_batch *fbatch);
>
> extern void __meminit kswapd_run(int nid);
> @@ -554,7 +491,7 @@ static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
>
> void lru_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, int nid);
> #else
> -static inline int mem_cgroup_swappiness(struct mem_cgroup *mem)
> +static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
> {
> return READ_ONCE(vm_swappiness);
> }
> diff --git a/mm/internal.h b/mm/internal.h
> index 5602393054f3..5475ba38a621 100644
> --- a/mm/internal.h
> +++ b/mm/internal.h
> @@ -24,6 +24,72 @@
>
> struct folio_batch;
>
> +bool workingset_test_recent(void *shadow, bool file, bool *workingset,
> + bool flush);
> +void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages);
> +void *workingset_eviction(struct folio *folio,
> + struct mem_cgroup *target_memcg);
> +void workingset_refault(struct folio *folio, void *shadow);
> +void workingset_activation(struct folio *folio);
> +
> +void lru_note_cost_unlock_irq(struct lruvec *lruvec, bool file,
> + unsigned int nr_io, unsigned int nr_rotated)
> + __releases(lruvec->lru_lock);
> +void lru_note_cost_refault(struct folio *folio);
> +void folio_add_lru_vma(struct folio *folio, struct vm_area_struct *vma);
> +
> +static inline bool folio_may_be_lru_cached(struct folio *folio)
> +{
> + /*
> + * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting.
> + * Holding small numbers of low-order mTHP folios in per-CPU LRU cache
> + * will be sensible, but nobody has implemented and tested that yet.
> + */
> + return !folio_test_large(folio);
> +}
> +
> +static inline void lru_cache_enable(void)
> +{
> + atomic_dec(&lru_disable_count);
> +}
> +
> +void lru_cache_disable(void);
> +void lru_add_drain(void);
> +void lru_add_drain_cpu(int cpu);
> +void lru_add_drain_cpu_zone(struct zone *zone);
> +void folio_deactivate(struct folio *folio);
> +void folio_mark_lazyfree(struct folio *folio);
> +void swap_readahead_setup(void);
> +
> +unsigned long zone_reclaimable_pages(struct zone *zone);
> +unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
> + gfp_t gfp_mask, nodemask_t *mask);
Skimming over this, what a confusing function name (having free_pages() etc in
mind). In particular, that it's interesting in a single high-order page judging
from the interface?
I wonder if making it clearer that this is a direct reclaim interface would
improve the situation.
"direct_reclaim_...()"
Similar for try_to_free_mem_cgroup_pages -- which actually consumes nr_pages.
Just a random thought ...
Moving a lot of stuff out of swap.h sounds like a good idea. I do wonder if
mm/internal.h should be split up as well (to minimize future conflicts).
--
Cheers,
David