Re:Re: [PATCH v2] mm/memory-failure: fix refcount leak on soft-offline LBS folio
李佑鸿 <[email protected]>
| Newsgroups | org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
At 2026-08-06 07:33:08, [email protected] wrote: > > >On 8/3/2026 8:53 PM, [email protected] wrote: >> From: liyouhong <liyouhong@ kylinos. cn> soft_offline_in_use_page() runs >> with a folio reference taken by get_hwpoison_page(). Soft-offline skips >> splitting when min_order_for_split() is non-zero, so large folios stay >> intact. That early return >> >> >> From: liyouhong <[email protected]> >> >> soft_offline_in_use_page() runs with a folio reference taken by >> get_hwpoison_page(). >> >> Soft-offline skips splitting when min_order_for_split() >> is non-zero, so large folios stay intact. That early >> return -EBUSY path never drops the reference. >> >> The other failure path is fine: try_to_split_thp_page(..., release=true) >> puts the page when the split itself fails. memory_failure() also puts >> explicitly on its analogous unsplit path. >> >> Handle the new_order != 0 case separately and call folio_put() >> before returning. >> >> Fixes: 689b8986776c ("mm/memory-failure: improve large block size folio handling") >> Signed-off-by: liyouhong <[email protected]> >> --- >> v2: >> - Add documentation for the folio reference counting convention of soft_offline_in_use_page(). >> - Remove MF_COUNT_INCREASED related description in commit message to avoid misleading. >> v1: https://lore.kernel.org/all/[email protected]/ >> >> --- >> mm/memory-failure.c | 17 +++++++++++++++-- >> 1 file changed, 15 insertions(+), 2 deletions(-) >> >> diff --git a/mm/memory-failure.c b/mm/memory-failure.c >> index 51508a55c405..3b1e6946821b 100644 >> --- a/mm/memory-failure.c >> +++ b/mm/memory-failure.c >> @@ -2776,6 +2776,9 @@ EXPORT_SYMBOL(unpoison_memory); >> * soft_offline_in_use_page handles hugetlb-pages and non-hugetlb pages. >> * If the page is a non-dirty unmapped page-cache page, it simply invalidates. >> * If the page is mapped, it migrates the contents over. >> + * >> + * The folio refcount has been incremented before entering this function. >> + * This folio reference must be released before the function returns on all paths. >> */ >> static int soft_offline_in_use_page(struct page *page) >> { >> @@ -2801,9 +2804,19 @@ static int soft_offline_in_use_page(struct page *page) >> * NOTE: if minimizing the number of soft offline pages is >> * preferred, split it to non-zero new_order like it is done in >> * memory_failure(). >> + * >> + * Drop the reference obtained upon entry; >> + * try_to_split_thp_page(..., release=true) handles refcounting itself >> + * when the split fails. >> */ >> - if (new_order || try_to_split_thp_page(page, /* new_order= */ 0, >> - /* release= */ true)) { >> + if (new_order) { >> + pr_info("%#lx: order-%d folio cannot soft offline\n", >> + pfn, new_order); >> + folio_put(folio); >> + return -EBUSY; >> + } >> + if (try_to_split_thp_page(page, /* new_order= */ 0, >> + /* release= */ true)) { >> pr_info("%#lx: thp split failed\n", pfn); >> return -EBUSY; >> } >> -- >> 2.25.1 >> > >It seems me this will do - > >--- a/mm/memory-failure.c >+++ b/mm/memory-failure.c >@@ -2802,8 +2802,8 @@ static int soft_offline_in_use_page(struct page *page) > * preferred, split it to non-zero new_order like it is >done in > * memory_failure(). > */ >- if (new_order || try_to_split_thp_page(page, /* >new_order= */ 0, >- /* release= */ >true)) { >+ if (new_order || try_to_split_thp_page(page, false)) { >+ put_page(page); > pr_info("%#lx: thp split failed\n", pfn); > return -EBUSY; > } > > Hi Jane, Thanks for the suggestion! I've ended up going with David's more comprehensive refactoring patch, which also fixes the refcount leak. The v4 series has been sent out: link:https://lore.kernel.org/all/[email protected]/ Thanks, Youhong