Re: [RFC PATCH v3 3/4] mm: drain LRU cache if necessary for splitting large folios

Barry Song <[email protected]>
Newsgroups org.kvack.linux-mm,org.kernel.vger.linux-kernel
Message-ID <CAGsJ_4z-PnFyBFm5BLVFtzxAbToReQVSgxPDYf_6RSkVHc9_jw@mail.gmail.com>
On Wed, Aug 19, 2026 at 6:59 AM Barry Song (Xiaomi) <[email protected]> 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) <[email protected]>
> ---
>  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
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.