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