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]>

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;
                 }


thanks,
-jane

>
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.