Re: [RFC PATCH v3 3/4] mm: drain LRU cache if necessary for splitting large folios
From: Barry Song
Date: Thu Aug 20 2026 - 06:20:56 EST
On Wed, Aug 19, 2026 at 6:59 AM Barry Song (Xiaomi) <baohua@xxxxxxxxxx> wrote:
>
> Smaller large folios might now be present in the LRU cache. Use David's
> new lru_cache_drain_for_folio() helper to drain the LRU cache before
> splitting a folio, ensuring that the folio can be split successfully.
>
> Also, we only perform the drain when it may actually help, assuming
> that the lru_cache holds an extra reference.
>
> Signed-off-by: Barry Song (Xiaomi) <baohua@xxxxxxxxxx>
> ---
> mm/huge_memory.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index ced400f72d43..263ef9b6949d 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -4201,6 +4201,9 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
> if (shmem_mapping(mapping))
> end = shmem_fallocend(mapping->host, end);
> }
> + if (folio_ref_count(folio) == folio_expected_ref_count(folio) + 1 +
> + folio_may_be_lru_cached(folio))
> + lru_cache_drain_for_folio(folio, 1, NULL);
>
> /*
> * Racy check if we can split the page, before unmap_folio() will
> @@ -4325,6 +4328,9 @@ int folio_split_unmapped(struct folio *folio, unsigned int new_order)
> VM_WARN_ON_ONCE_FOLIO(!folio_test_large(folio), folio);
> VM_WARN_ON_ONCE_FOLIO(!folio_test_anon(folio), folio);
>
> + if (folio_ref_count(folio) == folio_expected_ref_count(folio) + 1 +
> + folio_may_be_lru_cached(folio))
> + lru_cache_drain_for_folio(folio, 1, NULL);
> if (folio_expected_ref_count(folio) != folio_ref_count(folio) - 1)
> return -EAGAIN;
>
> @@ -4805,6 +4811,10 @@ static int split_huge_pages_pid(int pid, unsigned long vaddr_start,
> goto next;
>
> total++;
> +
> + if (folio_ref_count(folio) == folio_expected_ref_count(folio) +
> + folio_may_be_lru_cached(folio))
> + lru_cache_drain_for_folio(folio, 0, NULL);
sashiko says:
"Does calling lru_cache_drain_for_folio() here sleep inside an atomic context?
In split_huge_pages_pid(), this code executes between folio_walk_start() and
folio_walk_end() where the page table spinlock is held and preemption is
disabled.
If the condition is met, lru_cache_drain_for_folio() can call
lru_add_drain_all(), which acquires a mutex and flushes work, both of which
are blocking operations.
Can this result in a "scheduling while atomic" panic when writing to
/sys/kernel/debug/split_huge_pages?"
I guess I can either drop it since this is a debug interface, and
failing to split folios in lru_cache shouldn't cause any serious
issues, or move it before folio_walk_start().
> /*
> * For folios with private, split_huge_page_to_list_to_order()
> * will try to drop it before split and then check if the folio
> --
> 2.34.1
>
Best Regards
Barry