lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <5e864bfe-6817-4ec5-819f-9648a23abfa3@kernel.org>
Date: Tue, 18 Nov 2025 21:36:25 +0100
From: "David Hildenbrand (Red Hat)" <david@...nel.org>
To: Balbir Singh <balbirs@...dia.com>, linux-kernel@...r.kernel.org,
 linux-mm@...ck.org, dri-devel@...ts.freedesktop.org
Cc: Andrew Morton <akpm@...ux-foundation.org>, Zi Yan <ziy@...dia.com>,
 Joshua Hahn <joshua.hahnjy@...il.com>, Rakie Kim <rakie.kim@...com>,
 Byungchul Park <byungchul@...com>, Gregory Price <gourry@...rry.net>,
 Ying Huang <ying.huang@...ux.alibaba.com>,
 Alistair Popple <apopple@...dia.com>, Oscar Salvador <osalvador@...e.de>,
 Lorenzo Stoakes <lorenzo.stoakes@...cle.com>,
 Baolin Wang <baolin.wang@...ux.alibaba.com>,
 "Liam R. Howlett" <Liam.Howlett@...cle.com>, Nico Pache <npache@...hat.com>,
 Ryan Roberts <ryan.roberts@....com>, Dev Jain <dev.jain@....com>,
 Barry Song <baohua@...nel.org>, Lyude Paul <lyude@...hat.com>,
 Danilo Krummrich <dakr@...nel.org>, David Airlie <airlied@...il.com>,
 Simona Vetter <simona@...ll.ch>, Ralph Campbell <rcampbell@...dia.com>,
 Mika Penttilä <mpenttil@...hat.com>,
 Matthew Brost <matthew.brost@...el.com>,
 Francois Dugast <francois.dugast@...el.com>
Subject: Re: [PATCH v2] mm/huge_memory: introduce folio_split_unmapped

On 15.11.25 09:40, Balbir Singh wrote:
> Unmapped was added as a parameter to __folio_split() and related
> call sites to support splitting of folios already in the midst
> of a migration. This special case arose for device private folio
> migration since during migration there could be a disconnect between
> source and destination on the folio size.
> 
> Introduce folio_split_unmapped() to handle this special case. Also
> refactor code and add __folio_freeze_and_split_unmapped() helper that
> is common to both __folio_split() and folio_split_unmapped().
> 
> This in turn removes the special casing introduced by the unmapped
> parameter in __folio_split().
> 

I was briefly wondering: why can't we just detect at the beginning of 
the __folio_split() that the folio is unmapped (!folio_mapped()) and 
then continue assuming the folio is unmapped?

The folio is locked, so it shouldn't just become mapped again.

But then I looked into the details and figured that we will also not try 
to remap (replace migration entries) and focus on anon folios only.

I think we really have to document this properly. See below.

[...]

> +/*

Can we have proper kerneldoc?

> + * This function is a helper for splitting folios that have already been unmapped.
> + * The use case is that the device or the CPU can refuse to migrate THP pages in
> + * the middle of migration, due to allocation issues on either side
> + *
> + * The high level code is copied from __folio_split, since the pages are anonymous
> + * and are already isolated from the LRU, the code has been simplified to not
> + * burden __folio_split with unmapped sprinkled into the code.

Please drop the history of how this code was obtained :) Focus on 
ducmenting what the function does, what it expects from the caller, and 
what the result of the operation will be.

> + *
> + * None of the split folios are unlocked


Looking into the details, I think this function also does not

(a) remap the folio

(b) call things like free_folio_and_swap_cache()

Which locks do have to be held by the caller? I'd assume the anon vma 
lock and the folio lock?

Would this function currently work for anon folios that are in the 
swapcache?

And I assume this function works for ZONE_DEVICE and !ZONE_DEVICE?


Please carefully document all that (locks held, folio isolated, folio 
unmapped, will not remap the folio, anon folios only, etc).

> + */
> +int folio_split_unmapped(struct folio *folio, unsigned int new_order)
> +{
> +	int extra_pins, ret = 0;
> +
> +	VM_WARN_ON_ONCE_FOLIO(folio_mapped(folio), folio);
> +	VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio);
> +	VM_WARN_ON_ONCE_FOLIO(!folio_test_large(folio), folio);
> +	VM_WARN_ON_ONCE_FOLIO(!folio_test_anon(folio), folio);
> +
> +	if (!can_split_folio(folio, 1, &extra_pins))
> +		return -EAGAIN;
> +
> +	local_irq_disable();
> +	ret = __folio_freeze_and_split_unmapped(folio, new_order, &folio->page, NULL,
> +						NULL, false, NULL, SPLIT_TYPE_UNIFORM,
> +						0, NULL, extra_pins);
> +	local_irq_enable();
> +	return ret;
> +}
> +
>   /*
>    * This function splits a large folio into smaller folios of order @new_order.
>    * @page can point to any page of the large folio to split. The split operation
> @@ -4127,12 +4171,12 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
>    * with the folio. Splitting to order 0 is compatible with all folios.
>    */
>   int __split_huge_page_to_list_to_order(struct page *page, struct list_head *list,
> -				     unsigned int new_order, bool unmapped)
> +				     unsigned int new_order)
>   {
>   	struct folio *folio = page_folio(page);
>   
>   	return __folio_split(folio, new_order, &folio->page, page, list,
> -			     SPLIT_TYPE_UNIFORM, unmapped);
> +			     SPLIT_TYPE_UNIFORM);
>   }
>   
>   /**
> @@ -4163,7 +4207,7 @@ int folio_split(struct folio *folio, unsigned int new_order,
>   		struct page *split_at, struct list_head *list)
>   {
>   	return __folio_split(folio, new_order, split_at, &folio->page, list,
> -			     SPLIT_TYPE_NON_UNIFORM, false);
> +			     SPLIT_TYPE_NON_UNIFORM);
>   }
>   
>   int min_order_for_split(struct folio *folio)
> diff --git a/mm/migrate_device.c b/mm/migrate_device.c
> index 46dd68cfc503..05ce95f43ab9 100644
> --- a/mm/migrate_device.c
> +++ b/mm/migrate_device.c
> @@ -909,8 +909,7 @@ static int migrate_vma_split_unmapped_folio(struct migrate_vma *migrate,
>   
>   	folio_get(folio);
>   	split_huge_pmd_address(migrate->vma, addr, true);
> -	ret = __split_huge_page_to_list_to_order(folio_page(folio, 0), NULL,
> -							0, true);
> +	ret = folio_split_unmapped(folio, 0);
>   	if (ret)
>   		return ret;
>   	migrate->src[idx] &= ~MIGRATE_PFN_COMPOUND;

This is clearly a win.

-- 
Cheers

David

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ