The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling
@ 2026-06-30  2:15 Wei Yang
  2026-06-30  2:43 ` Lance Yang
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Wei Yang @ 2026-06-30  2:15 UTC (permalink / raw)
  To: akpm, david, ljs, riel, liam, vbabka, harry, jannh, balbirs, sj,
	ziy
  Cc: lance.yang, linux-mm, linux-kernel, Wei Yang, stable

Commit 65edfda6f3f2 ("mm/rmap: extend rmap and migration support
device-private entries") introduced the concept of device-private
PMD entries, but did not correctly update the rmap walk code to
account for them.

As a result, when page_vma_mapped_walk() encounters device-private
PMD entries, it takes no action other than to acquire the PMD lock
and exit.

However this is highly problematic for two reasons - firstly,
device private entries possess a PFN so check_pmd() needs to be
called to ensure an overlapping PFN range.

Secondly, and more importantly, if PVMW_MIGRATION is set the
caller assumes the returned entry is a migration entry, resulting
in memory corruption when the caller tries to interpret the device
private entry as such.

In addition, commit 146287290023 ("mm/huge_memory: implement
device-private THP splitting") allowed device private PMDs to be
split like THP mappings, but again did not update this code path.

As a result, we might race a PMD split prior to acquiring the PMD
lock.

This patch addresses all of these issues by invoking check_pmd(),
ensuring PMVW_MIGRATION is not set and checks whether a split raced
us we do for PMD THP and migration entries.

Instead of checking for a subset of the cases after taking the
pmd_lock(), put device-private along with pmd_trans_huge() and
pmd_is_migration_entry(). Also remove thp_migration_supported() as
it is already guarded by pmd_is_migration_entry().

Fixes: 65edfda6f3f2 ("mm/rmap: extend rmap and migration support device-private entries")
Cc: <stable@vger.kernel.org>
Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
Suggested-by: David Hildenbrand <david@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Balbir Singh <balbirs@nvidia.com>
Cc: SeongJae Park <sj@kernel.org>
Cc: Zi Yan <ziy@nvidia.com>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Lance Yang <lance.yang@linux.dev>

---
v5:
  * put device-private pmd handling along with the other two cases
  * remove thp_migration_supported()
v4: https://lore.kernel.org/all/20260624065353.1622-1-richard.weiyang@gmail.com/T/#u
  * refine subject and commit log based on Lorenzo's suggestion
  * put pmd device-private entry handling in its own if branch,
    suggested by Lorenzo

v3:
  * remove cleanup part, only fix the issue for device-private entry
  * refine user effect description based on Lorenzo's suggestion

v2: https://lore.kernel.org/all/20260616063436.20455-1-richard.weiyang@gmail.com/T/#u
  * specify the possible error case of current code and user visible effect
  * besides fix, cleanup the pmd entry handling based on David's suggestion

v1: https://lore.kernel.org/linux-mm/20260508013728.21285-1-richard.weiyang@gmail.com/
---
 mm/page_vma_mapped.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
index 2ccbabfb2cc1..2d6c58488e3a 100644
--- a/mm/page_vma_mapped.c
+++ b/mm/page_vma_mapped.c
@@ -243,21 +243,30 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
 		 */
 		pmde = pmdp_get_lockless(pvmw->pmd);
 
-		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde)) {
+		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
+		    pmd_is_device_private_entry(pmde)) {
 			pvmw->ptl = pmd_lock(mm, pvmw->pmd);
 			pmde = *pvmw->pmd;
-			if (!pmd_present(pmde)) {
+			if (pmd_is_migration_entry(pmde)) {
 				softleaf_t entry;
 
-				if (!thp_migration_supported() ||
-				    !(pvmw->flags & PVMW_MIGRATION))
+				if (!(pvmw->flags & PVMW_MIGRATION))
 					return not_found(pvmw);
 				entry = softleaf_from_pmd(pmde);
+				if (!check_pmd(softleaf_to_pfn(entry), pvmw))
+					return not_found(pvmw);
+				return true;
+			} else if (pmd_is_device_private_entry(pmde)) {
+				softleaf_t entry;
 
-				if (!softleaf_is_migration(entry) ||
-				    !check_pmd(softleaf_to_pfn(entry), pvmw))
+				if (pvmw->flags & PVMW_MIGRATION)
+					return not_found(pvmw);
+				entry = softleaf_from_pmd(pmde);
+				if (!check_pmd(softleaf_to_pfn(entry), pvmw))
 					return not_found(pvmw);
 				return true;
+			} else if (!pmd_present(pmde)) {
+				return not_found(pvmw);
 			}
 			if (likely(pmd_trans_huge(pmde))) {
 				if (pvmw->flags & PVMW_MIGRATION)
@@ -266,17 +275,10 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
 					return not_found(pvmw);
 				return true;
 			}
-			/* THP pmd was split under us: handle on pte level */
+			/* THP/device-private pmd was split under us: handle on pte level */
 			spin_unlock(pvmw->ptl);
 			pvmw->ptl = NULL;
 		} else if (!pmd_present(pmde)) {
-			const softleaf_t entry = softleaf_from_pmd(pmde);
-
-			if (softleaf_is_device_private(entry)) {
-				pvmw->ptl = pmd_lock(mm, pvmw->pmd);
-				return true;
-			}
-
 			if ((pvmw->flags & PVMW_SYNC) &&
 			    thp_vma_suitable_order(vma, pvmw->address,
 						   PMD_ORDER) &&
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling
  2026-06-30  2:15 [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling Wei Yang
@ 2026-06-30  2:43 ` Lance Yang
  2026-06-30  3:57 ` Balbir Singh
  2026-07-01 14:33 ` Klara Modin
  2 siblings, 0 replies; 9+ messages in thread
From: Lance Yang @ 2026-06-30  2:43 UTC (permalink / raw)
  To: Wei Yang
  Cc: liam, linux-mm, ljs, david, akpm, sj, balbirs, harry, jannh,
	linux-kernel, stable, vbabka, ziy, riel



On 2026/6/30 10:15, Wei Yang wrote:
> Commit 65edfda6f3f2 ("mm/rmap: extend rmap and migration support
> device-private entries") introduced the concept of device-private
> PMD entries, but did not correctly update the rmap walk code to
> account for them.
> 
> As a result, when page_vma_mapped_walk() encounters device-private
> PMD entries, it takes no action other than to acquire the PMD lock
> and exit.
> 
> However this is highly problematic for two reasons - firstly,
> device private entries possess a PFN so check_pmd() needs to be
> called to ensure an overlapping PFN range.
> 
> Secondly, and more importantly, if PVMW_MIGRATION is set the
> caller assumes the returned entry is a migration entry, resulting
> in memory corruption when the caller tries to interpret the device
> private entry as such.
> 
> In addition, commit 146287290023 ("mm/huge_memory: implement
> device-private THP splitting") allowed device private PMDs to be
> split like THP mappings, but again did not update this code path.
> 
> As a result, we might race a PMD split prior to acquiring the PMD
> lock.
> 
> This patch addresses all of these issues by invoking check_pmd(),
> ensuring PMVW_MIGRATION is not set and checks whether a split raced
> us we do for PMD THP and migration entries.
> 
> Instead of checking for a subset of the cases after taking the
> pmd_lock(), put device-private along with pmd_trans_huge() and
> pmd_is_migration_entry(). Also remove thp_migration_supported() as
> it is already guarded by pmd_is_migration_entry().
> 
> Fixes: 65edfda6f3f2 ("mm/rmap: extend rmap and migration support device-private entries")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
> Suggested-by: David Hildenbrand <david@kernel.org>
> Cc: David Hildenbrand <david@kernel.org>
> Cc: Balbir Singh <balbirs@nvidia.com>
> Cc: SeongJae Park <sj@kernel.org>
> Cc: Zi Yan <ziy@nvidia.com>
> Cc: Lorenzo Stoakes <ljs@kernel.org>
> Cc: Lance Yang <lance.yang@linux.dev>
> 
> ---

LGTM, thanks!

Reviewed-by: Lance Yang <lance.yang@linux.dev>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling
  2026-06-30  2:15 [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling Wei Yang
  2026-06-30  2:43 ` Lance Yang
@ 2026-06-30  3:57 ` Balbir Singh
  2026-07-01 14:33 ` Klara Modin
  2 siblings, 0 replies; 9+ messages in thread
From: Balbir Singh @ 2026-06-30  3:57 UTC (permalink / raw)
  To: Wei Yang
  Cc: akpm, david, ljs, riel, liam, vbabka, harry, jannh, sj, ziy,
	lance.yang, linux-mm, linux-kernel, stable

On Tue, Jun 30, 2026 at 02:15:40AM +0000, Wei Yang wrote:
> Commit 65edfda6f3f2 ("mm/rmap: extend rmap and migration support
> device-private entries") introduced the concept of device-private
> PMD entries, but did not correctly update the rmap walk code to
> account for them.
> 
> As a result, when page_vma_mapped_walk() encounters device-private
> PMD entries, it takes no action other than to acquire the PMD lock
> and exit.
> 
> However this is highly problematic for two reasons - firstly,
> device private entries possess a PFN so check_pmd() needs to be
> called to ensure an overlapping PFN range.
> 
> Secondly, and more importantly, if PVMW_MIGRATION is set the
> caller assumes the returned entry is a migration entry, resulting
> in memory corruption when the caller tries to interpret the device
> private entry as such.
> 
> In addition, commit 146287290023 ("mm/huge_memory: implement
> device-private THP splitting") allowed device private PMDs to be
> split like THP mappings, but again did not update this code path.
> 
> As a result, we might race a PMD split prior to acquiring the PMD
> lock.
> 
> This patch addresses all of these issues by invoking check_pmd(),
> ensuring PMVW_MIGRATION is not set and checks whether a split raced
> us we do for PMD THP and migration entries.
> 
> Instead of checking for a subset of the cases after taking the
> pmd_lock(), put device-private along with pmd_trans_huge() and
> pmd_is_migration_entry(). Also remove thp_migration_supported() as
> it is already guarded by pmd_is_migration_entry().
> 
> Fixes: 65edfda6f3f2 ("mm/rmap: extend rmap and migration support device-private entries")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
> Suggested-by: David Hildenbrand <david@kernel.org>
> Cc: David Hildenbrand <david@kernel.org>
> Cc: Balbir Singh <balbirs@nvidia.com>
> Cc: SeongJae Park <sj@kernel.org>
> Cc: Zi Yan <ziy@nvidia.com>
> Cc: Lorenzo Stoakes <ljs@kernel.org>
> Cc: Lance Yang <lance.yang@linux.dev>
> 
> ---
> v5:
>   * put device-private pmd handling along with the other two cases
>   * remove thp_migration_supported()
> v4: https://lore.kernel.org/all/20260624065353.1622-1-richard.weiyang@gmail.com/T/#u
>   * refine subject and commit log based on Lorenzo's suggestion
>   * put pmd device-private entry handling in its own if branch,
>     suggested by Lorenzo
> 
> v3:
>   * remove cleanup part, only fix the issue for device-private entry
>   * refine user effect description based on Lorenzo's suggestion
> 
> v2: https://lore.kernel.org/all/20260616063436.20455-1-richard.weiyang@gmail.com/T/#u
>   * specify the possible error case of current code and user visible effect
>   * besides fix, cleanup the pmd entry handling based on David's suggestion
> 
> v1: https://lore.kernel.org/linux-mm/20260508013728.21285-1-richard.weiyang@gmail.com/
> ---
>  mm/page_vma_mapped.c | 30 ++++++++++++++++--------------
>  1 file changed, 16 insertions(+), 14 deletions(-)
> 
> diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
> index 2ccbabfb2cc1..2d6c58488e3a 100644
> --- a/mm/page_vma_mapped.c
> +++ b/mm/page_vma_mapped.c
> @@ -243,21 +243,30 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
>  		 */
>  		pmde = pmdp_get_lockless(pvmw->pmd);
>  
> -		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde)) {
> +		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
> +		    pmd_is_device_private_entry(pmde)) {
>  			pvmw->ptl = pmd_lock(mm, pvmw->pmd);
>  			pmde = *pvmw->pmd;
> -			if (!pmd_present(pmde)) {
> +			if (pmd_is_migration_entry(pmde)) {
>  				softleaf_t entry;
>  
> -				if (!thp_migration_supported() ||
> -				    !(pvmw->flags & PVMW_MIGRATION))
> +				if (!(pvmw->flags & PVMW_MIGRATION))
>  					return not_found(pvmw);
>  				entry = softleaf_from_pmd(pmde);
> +				if (!check_pmd(softleaf_to_pfn(entry), pvmw))
> +					return not_found(pvmw);
> +				return true;
> +			} else if (pmd_is_device_private_entry(pmde)) {
> +				softleaf_t entry;
>  
> -				if (!softleaf_is_migration(entry) ||
> -				    !check_pmd(softleaf_to_pfn(entry), pvmw))
> +				if (pvmw->flags & PVMW_MIGRATION)
> +					return not_found(pvmw);
> +				entry = softleaf_from_pmd(pmde);
> +				if (!check_pmd(softleaf_to_pfn(entry), pvmw))
>  					return not_found(pvmw);
>  				return true;
> +			} else if (!pmd_present(pmde)) {
> +				return not_found(pvmw);
>  			}
>  			if (likely(pmd_trans_huge(pmde))) {
>  				if (pvmw->flags & PVMW_MIGRATION)
> @@ -266,17 +275,10 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
>  					return not_found(pvmw);
>  				return true;
>  			}
> -			/* THP pmd was split under us: handle on pte level */
> +			/* THP/device-private pmd was split under us: handle on pte level */
>  			spin_unlock(pvmw->ptl);
>  			pvmw->ptl = NULL;
>  		} else if (!pmd_present(pmde)) {
> -			const softleaf_t entry = softleaf_from_pmd(pmde);
> -
> -			if (softleaf_is_device_private(entry)) {
> -				pvmw->ptl = pmd_lock(mm, pvmw->pmd);
> -				return true;
> -			}
> -
>  			if ((pvmw->flags & PVMW_SYNC) &&
>  			    thp_vma_suitable_order(vma, pvmw->address,
>  						   PMD_ORDER) &&
> --

Thanks!

Acked-by: Balbir Singh <balbirs@nvidia.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling
  2026-06-30  2:15 [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling Wei Yang
  2026-06-30  2:43 ` Lance Yang
  2026-06-30  3:57 ` Balbir Singh
@ 2026-07-01 14:33 ` Klara Modin
  2026-07-01 15:36   ` David Hildenbrand (Arm)
  2 siblings, 1 reply; 9+ messages in thread
From: Klara Modin @ 2026-07-01 14:33 UTC (permalink / raw)
  To: Wei Yang
  Cc: akpm, david, ljs, riel, liam, vbabka, harry, jannh, balbirs, sj,
	ziy, lance.yang, linux-mm, linux-kernel, stable

[-- Attachment #1: Type: text/plain, Size: 10393 bytes --]

Hi,

On 2026-06-30 02:15:40 +0000, Wei Yang wrote:
> Commit 65edfda6f3f2 ("mm/rmap: extend rmap and migration support
> device-private entries") introduced the concept of device-private
> PMD entries, but did not correctly update the rmap walk code to
> account for them.
> 
> As a result, when page_vma_mapped_walk() encounters device-private
> PMD entries, it takes no action other than to acquire the PMD lock
> and exit.
> 
> However this is highly problematic for two reasons - firstly,
> device private entries possess a PFN so check_pmd() needs to be
> called to ensure an overlapping PFN range.
> 
> Secondly, and more importantly, if PVMW_MIGRATION is set the
> caller assumes the returned entry is a migration entry, resulting
> in memory corruption when the caller tries to interpret the device
> private entry as such.
> 
> In addition, commit 146287290023 ("mm/huge_memory: implement
> device-private THP splitting") allowed device private PMDs to be
> split like THP mappings, but again did not update this code path.
> 
> As a result, we might race a PMD split prior to acquiring the PMD
> lock.
> 
> This patch addresses all of these issues by invoking check_pmd(),
> ensuring PMVW_MIGRATION is not set and checks whether a split raced
> us we do for PMD THP and migration entries.
> 
> Instead of checking for a subset of the cases after taking the
> pmd_lock(), put device-private along with pmd_trans_huge() and
> pmd_is_migration_entry(). Also remove thp_migration_supported() as
> it is already guarded by pmd_is_migration_entry().

This results in a build bug for my Raspberry Pi 1:

 In file included from <command-line>:
 In function ‘check_pmd’,
     inlined from ‘page_vma_mapped_walk’ at /home/klara/git/linux/trees/bisect/mm/page_vma_mapped.c:256:10:
 /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:702:45: error: call to ‘__compiletime_assert_433’ declared with attribute error: BUILD_BUG failed
   702 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
       |                                             ^
 /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:683:25: note: in definition of macro ‘__compiletime_assert’
   683 |                         prefix ## suffix();                             \
       |                         ^~~~~~
 /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:702:9: note: in expansion of macro ‘_compiletime_assert’
   702 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
       |         ^~~~~~~~~~~~~~~~~~~
 /home/klara/git/linux/trees/bisect/include/linux/build_bug.h:40:37: note: in expansion of macro ‘compiletime_assert’
    40 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
       |                                     ^~~~~~~~~~~~~~~~~~
 /home/klara/git/linux/trees/bisect/include/linux/build_bug.h:60:21: note: in expansion of macro ‘BUILD_BUG_ON_MSG’
    60 | #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
       |                     ^~~~~~~~~~~~~~~~
 /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:113:28: note: in expansion of macro ‘BUILD_BUG’
   113 | #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
       |                            ^~~~~~~~~
 /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:117:26: note: in expansion of macro ‘HPAGE_PMD_SHIFT’
   117 | #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
       |                          ^~~~~~~~~~~~~~~
 /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:118:26: note: in expansion of macro ‘HPAGE_PMD_ORDER’
   118 | #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
       |                          ^~~~~~~~~~~~~~~
 /home/klara/git/linux/trees/bisect/mm/page_vma_mapped.c:142:20: note: in expansion of macro ‘HPAGE_PMD_NR’
   142 |         if ((pfn + HPAGE_PMD_NR - 1) < pvmw->pfn)
       |                    ^~~~~~~~~~~~

bisect log:

 # bad: [be5c93fa674f0fc3c8f359c2143abce6bbb422e6] Add linux-next specific files for 20260630
 git bisect start 'HEAD'
 # status: waiting for 'good' commit(s), 'bad' commit known
 # good: [dc59e4fea9d83f03bad6bddf3fa2e52491777482] Linux 7.2-rc1
 git bisect good dc59e4fea9d83f03bad6bddf3fa2e52491777482
 # bad: [6148219e90732fd06f5d7a498bda974e6a43ab4b] Merge branch 'nand/next' of https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git
 git bisect bad 6148219e90732fd06f5d7a498bda974e6a43ab4b
 # bad: [e0326ebe10191447ab8fa2e904080df7b743765e] Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
 git bisect bad e0326ebe10191447ab8fa2e904080df7b743765e
 # bad: [fbc9c5ac47cef5a2b04aef30c8e990b32dcf2548] Merge branch 'hwmon' of https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
 git bisect bad fbc9c5ac47cef5a2b04aef30c8e990b32dcf2548
 # bad: [e488171f6f6df6fc899a355079665fdb3c50b0e3] Merge branch 'for-linus' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
 git bisect bad e488171f6f6df6fc899a355079665fdb3c50b0e3
 # bad: [60db0fcb8fc9d80ac0b63041c632b41a311a45f1] Merge branch 'fs-current' of linux-next
 git bisect bad 60db0fcb8fc9d80ac0b63041c632b41a311a45f1
 # good: [51021d260d682aa17b3533848a99160ab83e0c93] Merge branch 'vfs.fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
 git bisect good 51021d260d682aa17b3533848a99160ab83e0c93
 # good: [ded56474db6552260786a65898322464b72c7540] mm: a second pagecache maintainer
 git bisect good ded56474db6552260786a65898322464b72c7540
 # good: [6c893b948351d42cfc3761cc746ab5b3d03ee7f3] Merge branch 'misc-7.2' into next-fixes
 git bisect good 6c893b948351d42cfc3761cc746ab5b3d03ee7f3
 # good: [bfcc55a14179495b0c41408908fd7b9d7785c694] lib: test_hmm: use device devt for coherent device range selection
 git bisect good bfcc55a14179495b0c41408908fd7b9d7785c694
 # good: [a27318567c92ba5482906d047e71a7aa4fd01889] Merge branch 'fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git
 git bisect good a27318567c92ba5482906d047e71a7aa4fd01889
 # bad: [6887a39652cdfd4cfd3b0962662c9cbc26ce5252] mm/page_vma_mapped: fix device-private PMD handling
 git bisect bad 6887a39652cdfd4cfd3b0962662c9cbc26ce5252
 # good: [2cc6bd0efc264b9ac760c2bc74dff4f521a680a1] MAINTAINERS: s/SeongJae/SJ/
 git bisect good 2cc6bd0efc264b9ac760c2bc74dff4f521a680a1
 # first 'bad' commit: [6887a39652cdfd4cfd3b0962662c9cbc26ce5252] mm/page_vma_mapped: fix device-private PMD handling

> 
> Fixes: 65edfda6f3f2 ("mm/rmap: extend rmap and migration support device-private entries")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
> Suggested-by: David Hildenbrand <david@kernel.org>
> Cc: David Hildenbrand <david@kernel.org>
> Cc: Balbir Singh <balbirs@nvidia.com>
> Cc: SeongJae Park <sj@kernel.org>
> Cc: Zi Yan <ziy@nvidia.com>
> Cc: Lorenzo Stoakes <ljs@kernel.org>
> Cc: Lance Yang <lance.yang@linux.dev>
> 
> ---
> v5:
>   * put device-private pmd handling along with the other two cases
>   * remove thp_migration_supported()
> v4: https://lore.kernel.org/all/20260624065353.1622-1-richard.weiyang@gmail.com/T/#u
>   * refine subject and commit log based on Lorenzo's suggestion
>   * put pmd device-private entry handling in its own if branch,
>     suggested by Lorenzo
> 
> v3:
>   * remove cleanup part, only fix the issue for device-private entry
>   * refine user effect description based on Lorenzo's suggestion
> 
> v2: https://lore.kernel.org/all/20260616063436.20455-1-richard.weiyang@gmail.com/T/#u
>   * specify the possible error case of current code and user visible effect
>   * besides fix, cleanup the pmd entry handling based on David's suggestion
> 
> v1: https://lore.kernel.org/linux-mm/20260508013728.21285-1-richard.weiyang@gmail.com/
> ---
>  mm/page_vma_mapped.c | 30 ++++++++++++++++--------------
>  1 file changed, 16 insertions(+), 14 deletions(-)
> 
> diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
> index 2ccbabfb2cc1..2d6c58488e3a 100644
> --- a/mm/page_vma_mapped.c
> +++ b/mm/page_vma_mapped.c
> @@ -243,21 +243,30 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
>  		 */
>  		pmde = pmdp_get_lockless(pvmw->pmd);
>  
> -		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde)) {
> +		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
> +		    pmd_is_device_private_entry(pmde)) {
>  			pvmw->ptl = pmd_lock(mm, pvmw->pmd);
>  			pmde = *pvmw->pmd;
> -			if (!pmd_present(pmde)) {
> +			if (pmd_is_migration_entry(pmde)) {
>  				softleaf_t entry;
>  
> -				if (!thp_migration_supported() ||
> -				    !(pvmw->flags & PVMW_MIGRATION))
> +				if (!(pvmw->flags & PVMW_MIGRATION))
>  					return not_found(pvmw);
>  				entry = softleaf_from_pmd(pmde);
> +				if (!check_pmd(softleaf_to_pfn(entry), pvmw))
> +					return not_found(pvmw);
> +				return true;
> +			} else if (pmd_is_device_private_entry(pmde)) {
> +				softleaf_t entry;
>  

> -				if (!softleaf_is_migration(entry) ||
> -				    !check_pmd(softleaf_to_pfn(entry), pvmw))

My only guess here would be that the compiler evaluates
!softleaf_is_migration(entry) to always be true and optimises away the
!check_pmd(softleaf_to_pfn(entry), pvmw) which is why this worked
before?

> +				if (pvmw->flags & PVMW_MIGRATION)
> +					return not_found(pvmw);
> +				entry = softleaf_from_pmd(pmde);
> +				if (!check_pmd(softleaf_to_pfn(entry), pvmw))
>  					return not_found(pvmw);
>  				return true;
> +			} else if (!pmd_present(pmde)) {
> +				return not_found(pvmw);
>  			}
>  			if (likely(pmd_trans_huge(pmde))) {
>  				if (pvmw->flags & PVMW_MIGRATION)
> @@ -266,17 +275,10 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
>  					return not_found(pvmw);
>  				return true;
>  			}
> -			/* THP pmd was split under us: handle on pte level */
> +			/* THP/device-private pmd was split under us: handle on pte level */
>  			spin_unlock(pvmw->ptl);
>  			pvmw->ptl = NULL;
>  		} else if (!pmd_present(pmde)) {
> -			const softleaf_t entry = softleaf_from_pmd(pmde);
> -
> -			if (softleaf_is_device_private(entry)) {
> -				pvmw->ptl = pmd_lock(mm, pvmw->pmd);
> -				return true;
> -			}
> -
>  			if ((pvmw->flags & PVMW_SYNC) &&
>  			    thp_vma_suitable_order(vma, pvmw->address,
>  						   PMD_ORDER) &&
> -- 
> 2.34.1
> 

Regards,
Klara Modin

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 23964 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling
  2026-07-01 14:33 ` Klara Modin
@ 2026-07-01 15:36   ` David Hildenbrand (Arm)
  2026-07-01 16:33     ` Lance Yang
  0 siblings, 1 reply; 9+ messages in thread
From: David Hildenbrand (Arm) @ 2026-07-01 15:36 UTC (permalink / raw)
  To: Klara Modin, Wei Yang
  Cc: akpm, ljs, riel, liam, vbabka, harry, jannh, balbirs, sj, ziy,
	lance.yang, linux-mm, linux-kernel, stable

On 7/1/26 16:33, Klara Modin wrote:
> Hi,
> 
> On 2026-06-30 02:15:40 +0000, Wei Yang wrote:
>> Commit 65edfda6f3f2 ("mm/rmap: extend rmap and migration support
>> device-private entries") introduced the concept of device-private
>> PMD entries, but did not correctly update the rmap walk code to
>> account for them.
>>
>> As a result, when page_vma_mapped_walk() encounters device-private
>> PMD entries, it takes no action other than to acquire the PMD lock
>> and exit.
>>
>> However this is highly problematic for two reasons - firstly,
>> device private entries possess a PFN so check_pmd() needs to be
>> called to ensure an overlapping PFN range.
>>
>> Secondly, and more importantly, if PVMW_MIGRATION is set the
>> caller assumes the returned entry is a migration entry, resulting
>> in memory corruption when the caller tries to interpret the device
>> private entry as such.
>>
>> In addition, commit 146287290023 ("mm/huge_memory: implement
>> device-private THP splitting") allowed device private PMDs to be
>> split like THP mappings, but again did not update this code path.
>>
>> As a result, we might race a PMD split prior to acquiring the PMD
>> lock.
>>
>> This patch addresses all of these issues by invoking check_pmd(),
>> ensuring PMVW_MIGRATION is not set and checks whether a split raced
>> us we do for PMD THP and migration entries.
>>
>> Instead of checking for a subset of the cases after taking the
>> pmd_lock(), put device-private along with pmd_trans_huge() and
>> pmd_is_migration_entry(). Also remove thp_migration_supported() as
>> it is already guarded by pmd_is_migration_entry().
> 
> This results in a build bug for my Raspberry Pi 1:
> 
>  In file included from <command-line>:
>  In function ‘check_pmd’,
>      inlined from ‘page_vma_mapped_walk’ at /home/klara/git/linux/trees/bisect/mm/page_vma_mapped.c:256:10:
>  /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:702:45: error: call to ‘__compiletime_assert_433’ declared with attribute error: BUILD_BUG failed
>    702 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>        |                                             ^
>  /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:683:25: note: in definition of macro ‘__compiletime_assert’
>    683 |                         prefix ## suffix();                             \
>        |                         ^~~~~~
>  /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:702:9: note: in expansion of macro ‘_compiletime_assert’
>    702 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>        |         ^~~~~~~~~~~~~~~~~~~
>  /home/klara/git/linux/trees/bisect/include/linux/build_bug.h:40:37: note: in expansion of macro ‘compiletime_assert’
>     40 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
>        |                                     ^~~~~~~~~~~~~~~~~~
>  /home/klara/git/linux/trees/bisect/include/linux/build_bug.h:60:21: note: in expansion of macro ‘BUILD_BUG_ON_MSG’
>     60 | #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
>        |                     ^~~~~~~~~~~~~~~~
>  /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:113:28: note: in expansion of macro ‘BUILD_BUG’
>    113 | #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
>        |                            ^~~~~~~~~
>  /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:117:26: note: in expansion of macro ‘HPAGE_PMD_SHIFT’
>    117 | #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
>        |                          ^~~~~~~~~~~~~~~
>  /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:118:26: note: in expansion of macro ‘HPAGE_PMD_ORDER’
>    118 | #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
>        |                          ^~~~~~~~~~~~~~~
>  /home/klara/git/linux/trees/bisect/mm/page_vma_mapped.c:142:20: note: in expansion of macro ‘HPAGE_PMD_NR’
>    142 |         if ((pfn + HPAGE_PMD_NR - 1) < pvmw->pfn)
>        |                    ^~~~~~~~~~~~
> 
> bisect log:
> 
>  # bad: [be5c93fa674f0fc3c8f359c2143abce6bbb422e6] Add linux-next specific files for 20260630
>  git bisect start 'HEAD'
>  # status: waiting for 'good' commit(s), 'bad' commit known
>  # good: [dc59e4fea9d83f03bad6bddf3fa2e52491777482] Linux 7.2-rc1
>  git bisect good dc59e4fea9d83f03bad6bddf3fa2e52491777482
>  # bad: [6148219e90732fd06f5d7a498bda974e6a43ab4b] Merge branch 'nand/next' of https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git
>  git bisect bad 6148219e90732fd06f5d7a498bda974e6a43ab4b
>  # bad: [e0326ebe10191447ab8fa2e904080df7b743765e] Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
>  git bisect bad e0326ebe10191447ab8fa2e904080df7b743765e
>  # bad: [fbc9c5ac47cef5a2b04aef30c8e990b32dcf2548] Merge branch 'hwmon' of https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
>  git bisect bad fbc9c5ac47cef5a2b04aef30c8e990b32dcf2548
>  # bad: [e488171f6f6df6fc899a355079665fdb3c50b0e3] Merge branch 'for-linus' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
>  git bisect bad e488171f6f6df6fc899a355079665fdb3c50b0e3
>  # bad: [60db0fcb8fc9d80ac0b63041c632b41a311a45f1] Merge branch 'fs-current' of linux-next
>  git bisect bad 60db0fcb8fc9d80ac0b63041c632b41a311a45f1
>  # good: [51021d260d682aa17b3533848a99160ab83e0c93] Merge branch 'vfs.fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
>  git bisect good 51021d260d682aa17b3533848a99160ab83e0c93
>  # good: [ded56474db6552260786a65898322464b72c7540] mm: a second pagecache maintainer
>  git bisect good ded56474db6552260786a65898322464b72c7540
>  # good: [6c893b948351d42cfc3761cc746ab5b3d03ee7f3] Merge branch 'misc-7.2' into next-fixes
>  git bisect good 6c893b948351d42cfc3761cc746ab5b3d03ee7f3
>  # good: [bfcc55a14179495b0c41408908fd7b9d7785c694] lib: test_hmm: use device devt for coherent device range selection
>  git bisect good bfcc55a14179495b0c41408908fd7b9d7785c694
>  # good: [a27318567c92ba5482906d047e71a7aa4fd01889] Merge branch 'fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git
>  git bisect good a27318567c92ba5482906d047e71a7aa4fd01889
>  # bad: [6887a39652cdfd4cfd3b0962662c9cbc26ce5252] mm/page_vma_mapped: fix device-private PMD handling
>  git bisect bad 6887a39652cdfd4cfd3b0962662c9cbc26ce5252
>  # good: [2cc6bd0efc264b9ac760c2bc74dff4f521a680a1] MAINTAINERS: s/SeongJae/SJ/
>  git bisect good 2cc6bd0efc264b9ac760c2bc74dff4f521a680a1
>  # first 'bad' commit: [6887a39652cdfd4cfd3b0962662c9cbc26ce5252] mm/page_vma_mapped: fix device-private PMD handling
> 
>>
>> Fixes: 65edfda6f3f2 ("mm/rmap: extend rmap and migration support device-private entries")
>> Cc: <stable@vger.kernel.org>
>> Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
>> Suggested-by: David Hildenbrand <david@kernel.org>
>> Cc: David Hildenbrand <david@kernel.org>
>> Cc: Balbir Singh <balbirs@nvidia.com>
>> Cc: SeongJae Park <sj@kernel.org>
>> Cc: Zi Yan <ziy@nvidia.com>
>> Cc: Lorenzo Stoakes <ljs@kernel.org>
>> Cc: Lance Yang <lance.yang@linux.dev>
>>
>> ---
>> v5:
>>   * put device-private pmd handling along with the other two cases
>>   * remove thp_migration_supported()
>> v4: https://lore.kernel.org/all/20260624065353.1622-1-richard.weiyang@gmail.com/T/#u
>>   * refine subject and commit log based on Lorenzo's suggestion
>>   * put pmd device-private entry handling in its own if branch,
>>     suggested by Lorenzo
>>
>> v3:
>>   * remove cleanup part, only fix the issue for device-private entry
>>   * refine user effect description based on Lorenzo's suggestion
>>
>> v2: https://lore.kernel.org/all/20260616063436.20455-1-richard.weiyang@gmail.com/T/#u
>>   * specify the possible error case of current code and user visible effect
>>   * besides fix, cleanup the pmd entry handling based on David's suggestion
>>
>> v1: https://lore.kernel.org/linux-mm/20260508013728.21285-1-richard.weiyang@gmail.com/
>> ---
>>  mm/page_vma_mapped.c | 30 ++++++++++++++++--------------
>>  1 file changed, 16 insertions(+), 14 deletions(-)
>>
>> diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
>> index 2ccbabfb2cc1..2d6c58488e3a 100644
>> --- a/mm/page_vma_mapped.c
>> +++ b/mm/page_vma_mapped.c
>> @@ -243,21 +243,30 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
>>  		 */
>>  		pmde = pmdp_get_lockless(pvmw->pmd);
>>  
>> -		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde)) {
>> +		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
>> +		    pmd_is_device_private_entry(pmde)) {
>>  			pvmw->ptl = pmd_lock(mm, pvmw->pmd);
>>  			pmde = *pvmw->pmd;
>> -			if (!pmd_present(pmde)) {
>> +			if (pmd_is_migration_entry(pmde)) {
>>  				softleaf_t entry;
>>  
>> -				if (!thp_migration_supported() ||
>> -				    !(pvmw->flags & PVMW_MIGRATION))
>> +				if (!(pvmw->flags & PVMW_MIGRATION))
>>  					return not_found(pvmw);
>>  				entry = softleaf_from_pmd(pmde);
>> +				if (!check_pmd(softleaf_to_pfn(entry), pvmw))
>> +					return not_found(pvmw);
>> +				return true;
>> +			} else if (pmd_is_device_private_entry(pmde)) {
>> +				softleaf_t entry;
>>  
> 
>> -				if (!softleaf_is_migration(entry) ||
>> -				    !check_pmd(softleaf_to_pfn(entry), pvmw))
> 
> My only guess here would be that the compiler evaluates
> !softleaf_is_migration(entry) to always be true and optimises away the
> !check_pmd(softleaf_to_pfn(entry), pvmw) which is why this worked
> before?

Weird, we enter this path only with

pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
pmd_is_device_private_entry(pmde)

If any one of these would compile for !CONFIG_TRANSPARENT_HUGEPAGE that would be
odd.

pmd_is_device_private_entry() is hard-coded to false unless
CONFIG_ARCH_ENABLE_THP_MIGRATION. Which is only selected with
ARCH_ENABLE_THP_MIGRATION.

pmd_trans_huge() as well.

Maybe it's struggling with pmd_is_migration_entry() on some (older) compilers?
(not innlining stuff and not properly optimizing it out).

The whole conditional must be optimized out.

We could check for IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) right at the start
to make it easier for the compiler:

if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) &&
    (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
     pmd_is_device_private_entry(pmde))) {


-- 
Cheers,

David

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling
  2026-07-01 15:36   ` David Hildenbrand (Arm)
@ 2026-07-01 16:33     ` Lance Yang
  2026-07-01 16:46       ` Klara Modin
  0 siblings, 1 reply; 9+ messages in thread
From: Lance Yang @ 2026-07-01 16:33 UTC (permalink / raw)
  To: david, klarasmodin
  Cc: richard.weiyang, akpm, ljs, riel, liam, vbabka, harry, jannh,
	balbirs, sj, ziy, lance.yang, linux-mm, linux-kernel, stable


On Wed, Jul 01, 2026 at 05:36:33PM +0200, David Hildenbrand (Arm) wrote:
>On 7/1/26 16:33, Klara Modin wrote:
>> Hi,

Hi,

[...]
>> 
>> This results in a build bug for my Raspberry Pi 1:

Thanks for reporting this!

>>  In file included from <command-line>:
>>  In function ‘check_pmd’,
>>      inlined from ‘page_vma_mapped_walk’ at /home/klara/git/linux/trees/bisect/mm/page_vma_mapped.c:256:10:
>>  /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:702:45: error: call to ‘__compiletime_assert_433’ declared with attribute error: BUILD_BUG failed
>>    702 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>>        |                                             ^
>>  /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:683:25: note: in definition of macro ‘__compiletime_assert’
>>    683 |                         prefix ## suffix();                             \
>>        |                         ^~~~~~
>>  /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:702:9: note: in expansion of macro ‘_compiletime_assert’
>>    702 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>>        |         ^~~~~~~~~~~~~~~~~~~
>>  /home/klara/git/linux/trees/bisect/include/linux/build_bug.h:40:37: note: in expansion of macro ‘compiletime_assert’
>>     40 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
>>        |                                     ^~~~~~~~~~~~~~~~~~
>>  /home/klara/git/linux/trees/bisect/include/linux/build_bug.h:60:21: note: in expansion of macro ‘BUILD_BUG_ON_MSG’
>>     60 | #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
>>        |                     ^~~~~~~~~~~~~~~~
>>  /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:113:28: note: in expansion of macro ‘BUILD_BUG’
>>    113 | #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
>>        |                            ^~~~~~~~~
>>  /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:117:26: note: in expansion of macro ‘HPAGE_PMD_SHIFT’
>>    117 | #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
>>        |                          ^~~~~~~~~~~~~~~
>>  /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:118:26: note: in expansion of macro ‘HPAGE_PMD_ORDER’
>>    118 | #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
>>        |                          ^~~~~~~~~~~~~~~
>>  /home/klara/git/linux/trees/bisect/mm/page_vma_mapped.c:142:20: note: in expansion of macro ‘HPAGE_PMD_NR’
>>    142 |         if ((pfn + HPAGE_PMD_NR - 1) < pvmw->pfn)
>>        |                    ^~~~~~~~~~~~
>> 
>> bisect log:
>> 
>>  # bad: [be5c93fa674f0fc3c8f359c2143abce6bbb422e6] Add linux-next specific files for 20260630
>>  git bisect start 'HEAD'
>>  # status: waiting for 'good' commit(s), 'bad' commit known
>>  # good: [dc59e4fea9d83f03bad6bddf3fa2e52491777482] Linux 7.2-rc1
>>  git bisect good dc59e4fea9d83f03bad6bddf3fa2e52491777482
>>  # bad: [6148219e90732fd06f5d7a498bda974e6a43ab4b] Merge branch 'nand/next' of https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git
>>  git bisect bad 6148219e90732fd06f5d7a498bda974e6a43ab4b
>>  # bad: [e0326ebe10191447ab8fa2e904080df7b743765e] Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
>>  git bisect bad e0326ebe10191447ab8fa2e904080df7b743765e
>>  # bad: [fbc9c5ac47cef5a2b04aef30c8e990b32dcf2548] Merge branch 'hwmon' of https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
>>  git bisect bad fbc9c5ac47cef5a2b04aef30c8e990b32dcf2548
>>  # bad: [e488171f6f6df6fc899a355079665fdb3c50b0e3] Merge branch 'for-linus' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
>>  git bisect bad e488171f6f6df6fc899a355079665fdb3c50b0e3
>>  # bad: [60db0fcb8fc9d80ac0b63041c632b41a311a45f1] Merge branch 'fs-current' of linux-next
>>  git bisect bad 60db0fcb8fc9d80ac0b63041c632b41a311a45f1
>>  # good: [51021d260d682aa17b3533848a99160ab83e0c93] Merge branch 'vfs.fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
>>  git bisect good 51021d260d682aa17b3533848a99160ab83e0c93
>>  # good: [ded56474db6552260786a65898322464b72c7540] mm: a second pagecache maintainer
>>  git bisect good ded56474db6552260786a65898322464b72c7540
>>  # good: [6c893b948351d42cfc3761cc746ab5b3d03ee7f3] Merge branch 'misc-7.2' into next-fixes
>>  git bisect good 6c893b948351d42cfc3761cc746ab5b3d03ee7f3
>>  # good: [bfcc55a14179495b0c41408908fd7b9d7785c694] lib: test_hmm: use device devt for coherent device range selection
>>  git bisect good bfcc55a14179495b0c41408908fd7b9d7785c694
>>  # good: [a27318567c92ba5482906d047e71a7aa4fd01889] Merge branch 'fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git
>>  git bisect good a27318567c92ba5482906d047e71a7aa4fd01889
>>  # bad: [6887a39652cdfd4cfd3b0962662c9cbc26ce5252] mm/page_vma_mapped: fix device-private PMD handling
>>  git bisect bad 6887a39652cdfd4cfd3b0962662c9cbc26ce5252
>>  # good: [2cc6bd0efc264b9ac760c2bc74dff4f521a680a1] MAINTAINERS: s/SeongJae/SJ/
>>  git bisect good 2cc6bd0efc264b9ac760c2bc74dff4f521a680a1
>>  # first 'bad' commit: [6887a39652cdfd4cfd3b0962662c9cbc26ce5252] mm/page_vma_mapped: fix device-private PMD handling
>> 
>>>
>>> Fixes: 65edfda6f3f2 ("mm/rmap: extend rmap and migration support device-private entries")
>>> Cc: <stable@vger.kernel.org>
>>> Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
>>> Suggested-by: David Hildenbrand <david@kernel.org>
>>> Cc: David Hildenbrand <david@kernel.org>
>>> Cc: Balbir Singh <balbirs@nvidia.com>
>>> Cc: SeongJae Park <sj@kernel.org>
>>> Cc: Zi Yan <ziy@nvidia.com>
>>> Cc: Lorenzo Stoakes <ljs@kernel.org>
>>> Cc: Lance Yang <lance.yang@linux.dev>
>>>
>>> ---
>>> v5:
>>>   * put device-private pmd handling along with the other two cases
>>>   * remove thp_migration_supported()
>>> v4: https://lore.kernel.org/all/20260624065353.1622-1-richard.weiyang@gmail.com/T/#u
>>>   * refine subject and commit log based on Lorenzo's suggestion
>>>   * put pmd device-private entry handling in its own if branch,
>>>     suggested by Lorenzo
>>>
>>> v3:
>>>   * remove cleanup part, only fix the issue for device-private entry
>>>   * refine user effect description based on Lorenzo's suggestion
>>>
>>> v2: https://lore.kernel.org/all/20260616063436.20455-1-richard.weiyang@gmail.com/T/#u
>>>   * specify the possible error case of current code and user visible effect
>>>   * besides fix, cleanup the pmd entry handling based on David's suggestion
>>>
>>> v1: https://lore.kernel.org/linux-mm/20260508013728.21285-1-richard.weiyang@gmail.com/
>>> ---
>>>  mm/page_vma_mapped.c | 30 ++++++++++++++++--------------
>>>  1 file changed, 16 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
>>> index 2ccbabfb2cc1..2d6c58488e3a 100644
>>> --- a/mm/page_vma_mapped.c
>>> +++ b/mm/page_vma_mapped.c
>>> @@ -243,21 +243,30 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
>>>  		 */
>>>  		pmde = pmdp_get_lockless(pvmw->pmd);
>>>  
>>> -		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde)) {
>>> +		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
>>> +		    pmd_is_device_private_entry(pmde)) {
>>>  			pvmw->ptl = pmd_lock(mm, pvmw->pmd);
>>>  			pmde = *pvmw->pmd;
>>> -			if (!pmd_present(pmde)) {
>>> +			if (pmd_is_migration_entry(pmde)) {
>>>  				softleaf_t entry;
>>>  
>>> -				if (!thp_migration_supported() ||
>>> -				    !(pvmw->flags & PVMW_MIGRATION))
>>> +				if (!(pvmw->flags & PVMW_MIGRATION))
>>>  					return not_found(pvmw);
>>>  				entry = softleaf_from_pmd(pmde);
>>> +				if (!check_pmd(softleaf_to_pfn(entry), pvmw))
>>> +					return not_found(pvmw);
>>> +				return true;
>>> +			} else if (pmd_is_device_private_entry(pmde)) {
>>> +				softleaf_t entry;
>>>  
>> 
>>> -				if (!softleaf_is_migration(entry) ||
>>> -				    !check_pmd(softleaf_to_pfn(entry), pvmw))
>> 
>> My only guess here would be that the compiler evaluates
>> !softleaf_is_migration(entry) to always be true and optimises away the
>> !check_pmd(softleaf_to_pfn(entry), pvmw) which is why this worked
>> before?
>
>Weird, we enter this path only with
>
>pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
>pmd_is_device_private_entry(pmde)
>
>If any one of these would compile for !CONFIG_TRANSPARENT_HUGEPAGE that would be
>odd.
>
>pmd_is_device_private_entry() is hard-coded to false unless
>CONFIG_ARCH_ENABLE_THP_MIGRATION. Which is only selected with
>ARCH_ENABLE_THP_MIGRATION.
>
>pmd_trans_huge() as well.
>
>Maybe it's struggling with pmd_is_migration_entry() on some (older) compilers?
>(not innlining stuff and not properly optimizing it out).
>
>The whole conditional must be optimized out.

Right. Kinda weird if compiler didn't fold

pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
pmd_is_device_private_entry(pmde)

away here ...

>We could check for IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) right at the start
>to make it easier for the compiler:

+1, explicit THP guard should do the trick :)

>if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) &&
>    (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
>     pmd_is_device_private_entry(pmde))) {
>
>

Klara, could you try with this change and see if it fixes the build?

Thanks, Lance

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling
  2026-07-01 16:33     ` Lance Yang
@ 2026-07-01 16:46       ` Klara Modin
  2026-07-02  1:47         ` Lance Yang
  2026-07-02 17:49         ` Lorenzo Stoakes
  0 siblings, 2 replies; 9+ messages in thread
From: Klara Modin @ 2026-07-01 16:46 UTC (permalink / raw)
  To: Lance Yang
  Cc: david, richard.weiyang, akpm, ljs, riel, liam, vbabka, harry,
	jannh, balbirs, sj, ziy, linux-mm, linux-kernel, stable

On 2026-07-02 00:33:56 +0800, Lance Yang wrote:
> 
> On Wed, Jul 01, 2026 at 05:36:33PM +0200, David Hildenbrand (Arm) wrote:
> >On 7/1/26 16:33, Klara Modin wrote:
> >> Hi,
> 
> Hi,
> 
> [...]
> >> 
> >> This results in a build bug for my Raspberry Pi 1:
> 
> Thanks for reporting this!
> 
> >>  In file included from <command-line>:
> >>  In function ‘check_pmd’,
> >>      inlined from ‘page_vma_mapped_walk’ at /home/klara/git/linux/trees/bisect/mm/page_vma_mapped.c:256:10:
> >>  /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:702:45: error: call to ‘__compiletime_assert_433’ declared with attribute error: BUILD_BUG failed
> >>    702 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
> >>        |                                             ^
> >>  /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:683:25: note: in definition of macro ‘__compiletime_assert’
> >>    683 |                         prefix ## suffix();                             \
> >>        |                         ^~~~~~
> >>  /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:702:9: note: in expansion of macro ‘_compiletime_assert’
> >>    702 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
> >>        |         ^~~~~~~~~~~~~~~~~~~
> >>  /home/klara/git/linux/trees/bisect/include/linux/build_bug.h:40:37: note: in expansion of macro ‘compiletime_assert’
> >>     40 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> >>        |                                     ^~~~~~~~~~~~~~~~~~
> >>  /home/klara/git/linux/trees/bisect/include/linux/build_bug.h:60:21: note: in expansion of macro ‘BUILD_BUG_ON_MSG’
> >>     60 | #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> >>        |                     ^~~~~~~~~~~~~~~~
> >>  /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:113:28: note: in expansion of macro ‘BUILD_BUG’
> >>    113 | #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
> >>        |                            ^~~~~~~~~
> >>  /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:117:26: note: in expansion of macro ‘HPAGE_PMD_SHIFT’
> >>    117 | #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
> >>        |                          ^~~~~~~~~~~~~~~
> >>  /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:118:26: note: in expansion of macro ‘HPAGE_PMD_ORDER’
> >>    118 | #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
> >>        |                          ^~~~~~~~~~~~~~~
> >>  /home/klara/git/linux/trees/bisect/mm/page_vma_mapped.c:142:20: note: in expansion of macro ‘HPAGE_PMD_NR’
> >>    142 |         if ((pfn + HPAGE_PMD_NR - 1) < pvmw->pfn)
> >>        |                    ^~~~~~~~~~~~
> >> 
> >> bisect log:
> >> 
> >>  # bad: [be5c93fa674f0fc3c8f359c2143abce6bbb422e6] Add linux-next specific files for 20260630
> >>  git bisect start 'HEAD'
> >>  # status: waiting for 'good' commit(s), 'bad' commit known
> >>  # good: [dc59e4fea9d83f03bad6bddf3fa2e52491777482] Linux 7.2-rc1
> >>  git bisect good dc59e4fea9d83f03bad6bddf3fa2e52491777482
> >>  # bad: [6148219e90732fd06f5d7a498bda974e6a43ab4b] Merge branch 'nand/next' of https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git
> >>  git bisect bad 6148219e90732fd06f5d7a498bda974e6a43ab4b
> >>  # bad: [e0326ebe10191447ab8fa2e904080df7b743765e] Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
> >>  git bisect bad e0326ebe10191447ab8fa2e904080df7b743765e
> >>  # bad: [fbc9c5ac47cef5a2b04aef30c8e990b32dcf2548] Merge branch 'hwmon' of https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
> >>  git bisect bad fbc9c5ac47cef5a2b04aef30c8e990b32dcf2548
> >>  # bad: [e488171f6f6df6fc899a355079665fdb3c50b0e3] Merge branch 'for-linus' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
> >>  git bisect bad e488171f6f6df6fc899a355079665fdb3c50b0e3
> >>  # bad: [60db0fcb8fc9d80ac0b63041c632b41a311a45f1] Merge branch 'fs-current' of linux-next
> >>  git bisect bad 60db0fcb8fc9d80ac0b63041c632b41a311a45f1
> >>  # good: [51021d260d682aa17b3533848a99160ab83e0c93] Merge branch 'vfs.fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
> >>  git bisect good 51021d260d682aa17b3533848a99160ab83e0c93
> >>  # good: [ded56474db6552260786a65898322464b72c7540] mm: a second pagecache maintainer
> >>  git bisect good ded56474db6552260786a65898322464b72c7540
> >>  # good: [6c893b948351d42cfc3761cc746ab5b3d03ee7f3] Merge branch 'misc-7.2' into next-fixes
> >>  git bisect good 6c893b948351d42cfc3761cc746ab5b3d03ee7f3
> >>  # good: [bfcc55a14179495b0c41408908fd7b9d7785c694] lib: test_hmm: use device devt for coherent device range selection
> >>  git bisect good bfcc55a14179495b0c41408908fd7b9d7785c694
> >>  # good: [a27318567c92ba5482906d047e71a7aa4fd01889] Merge branch 'fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git
> >>  git bisect good a27318567c92ba5482906d047e71a7aa4fd01889
> >>  # bad: [6887a39652cdfd4cfd3b0962662c9cbc26ce5252] mm/page_vma_mapped: fix device-private PMD handling
> >>  git bisect bad 6887a39652cdfd4cfd3b0962662c9cbc26ce5252
> >>  # good: [2cc6bd0efc264b9ac760c2bc74dff4f521a680a1] MAINTAINERS: s/SeongJae/SJ/
> >>  git bisect good 2cc6bd0efc264b9ac760c2bc74dff4f521a680a1
> >>  # first 'bad' commit: [6887a39652cdfd4cfd3b0962662c9cbc26ce5252] mm/page_vma_mapped: fix device-private PMD handling
> >> 
> >>>
> >>> Fixes: 65edfda6f3f2 ("mm/rmap: extend rmap and migration support device-private entries")
> >>> Cc: <stable@vger.kernel.org>
> >>> Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
> >>> Suggested-by: David Hildenbrand <david@kernel.org>
> >>> Cc: David Hildenbrand <david@kernel.org>
> >>> Cc: Balbir Singh <balbirs@nvidia.com>
> >>> Cc: SeongJae Park <sj@kernel.org>
> >>> Cc: Zi Yan <ziy@nvidia.com>
> >>> Cc: Lorenzo Stoakes <ljs@kernel.org>
> >>> Cc: Lance Yang <lance.yang@linux.dev>
> >>>
> >>> ---
> >>> v5:
> >>>   * put device-private pmd handling along with the other two cases
> >>>   * remove thp_migration_supported()
> >>> v4: https://lore.kernel.org/all/20260624065353.1622-1-richard.weiyang@gmail.com/T/#u
> >>>   * refine subject and commit log based on Lorenzo's suggestion
> >>>   * put pmd device-private entry handling in its own if branch,
> >>>     suggested by Lorenzo
> >>>
> >>> v3:
> >>>   * remove cleanup part, only fix the issue for device-private entry
> >>>   * refine user effect description based on Lorenzo's suggestion
> >>>
> >>> v2: https://lore.kernel.org/all/20260616063436.20455-1-richard.weiyang@gmail.com/T/#u
> >>>   * specify the possible error case of current code and user visible effect
> >>>   * besides fix, cleanup the pmd entry handling based on David's suggestion
> >>>
> >>> v1: https://lore.kernel.org/linux-mm/20260508013728.21285-1-richard.weiyang@gmail.com/
> >>> ---
> >>>  mm/page_vma_mapped.c | 30 ++++++++++++++++--------------
> >>>  1 file changed, 16 insertions(+), 14 deletions(-)
> >>>
> >>> diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
> >>> index 2ccbabfb2cc1..2d6c58488e3a 100644
> >>> --- a/mm/page_vma_mapped.c
> >>> +++ b/mm/page_vma_mapped.c
> >>> @@ -243,21 +243,30 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
> >>>  		 */
> >>>  		pmde = pmdp_get_lockless(pvmw->pmd);
> >>>  
> >>> -		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde)) {
> >>> +		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
> >>> +		    pmd_is_device_private_entry(pmde)) {
> >>>  			pvmw->ptl = pmd_lock(mm, pvmw->pmd);
> >>>  			pmde = *pvmw->pmd;
> >>> -			if (!pmd_present(pmde)) {
> >>> +			if (pmd_is_migration_entry(pmde)) {
> >>>  				softleaf_t entry;
> >>>  
> >>> -				if (!thp_migration_supported() ||
> >>> -				    !(pvmw->flags & PVMW_MIGRATION))
> >>> +				if (!(pvmw->flags & PVMW_MIGRATION))
> >>>  					return not_found(pvmw);
> >>>  				entry = softleaf_from_pmd(pmde);
> >>> +				if (!check_pmd(softleaf_to_pfn(entry), pvmw))
> >>> +					return not_found(pvmw);
> >>> +				return true;
> >>> +			} else if (pmd_is_device_private_entry(pmde)) {
> >>> +				softleaf_t entry;
> >>>  
> >> 
> >>> -				if (!softleaf_is_migration(entry) ||
> >>> -				    !check_pmd(softleaf_to_pfn(entry), pvmw))
> >> 
> >> My only guess here would be that the compiler evaluates
> >> !softleaf_is_migration(entry) to always be true and optimises away the
> >> !check_pmd(softleaf_to_pfn(entry), pvmw) which is why this worked
> >> before?
> >
> >Weird, we enter this path only with
> >
> >pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
> >pmd_is_device_private_entry(pmde)
> >
> >If any one of these would compile for !CONFIG_TRANSPARENT_HUGEPAGE that would be
> >odd.
> >
> >pmd_is_device_private_entry() is hard-coded to false unless
> >CONFIG_ARCH_ENABLE_THP_MIGRATION. Which is only selected with
> >ARCH_ENABLE_THP_MIGRATION.
> >
> >pmd_trans_huge() as well.
> >
> >Maybe it's struggling with pmd_is_migration_entry() on some (older) compilers?
> >(not innlining stuff and not properly optimizing it out).

It's a GCC 16 cross-compiler for armv6 so I wouldn't call it old :)

> >
> >The whole conditional must be optimized out.
> 
> Right. Kinda weird if compiler didn't fold
> 
> pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
> pmd_is_device_private_entry(pmde)
> 
> away here ...
> 
> >We could check for IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) right at the start
> >to make it easier for the compiler:
> 
> +1, explicit THP guard should do the trick :)
> 
> >if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) &&
> >    (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
> >     pmd_is_device_private_entry(pmde))) {
> >
> >
> 
> Klara, could you try with this change and see if it fixes the build?
> 
> Thanks, Lance

This does indeed make it build.

Thanks,
Klara Modin

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling
  2026-07-01 16:46       ` Klara Modin
@ 2026-07-02  1:47         ` Lance Yang
  2026-07-02 17:49         ` Lorenzo Stoakes
  1 sibling, 0 replies; 9+ messages in thread
From: Lance Yang @ 2026-07-02  1:47 UTC (permalink / raw)
  To: Klara Modin
  Cc: david, richard.weiyang, akpm, ljs, riel, liam, vbabka, harry,
	jannh, balbirs, sj, ziy, linux-mm, linux-kernel, stable



On 2026/7/2 00:46, Klara Modin wrote:
[...]
>>>>
>>>> My only guess here would be that the compiler evaluates
>>>> !softleaf_is_migration(entry) to always be true and optimises away the
>>>> !check_pmd(softleaf_to_pfn(entry), pvmw) which is why this worked
>>>> before?
>>>
>>> Weird, we enter this path only with
>>>
>>> pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
>>> pmd_is_device_private_entry(pmde)
>>>
>>> If any one of these would compile for !CONFIG_TRANSPARENT_HUGEPAGE that would be
>>> odd.
>>>
>>> pmd_is_device_private_entry() is hard-coded to false unless
>>> CONFIG_ARCH_ENABLE_THP_MIGRATION. Which is only selected with
>>> ARCH_ENABLE_THP_MIGRATION.
>>>
>>> pmd_trans_huge() as well.
>>>
>>> Maybe it's struggling with pmd_is_migration_entry() on some (older) compilers?
>>> (not innlining stuff and not properly optimizing it out).
> 
> It's a GCC 16 cross-compiler for armv6 so I wouldn't call it old :)
> 
>>>
>>> The whole conditional must be optimized out.
>>
>> Right. Kinda weird if compiler didn't fold
>>
>> pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
>> pmd_is_device_private_entry(pmde)
>>
>> away here ...
>>
>>> We could check for IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) right at the start
>>> to make it easier for the compiler:
>>
>> +1, explicit THP guard should do the trick :)
>>
>>> if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) &&
>>>     (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
>>>      pmd_is_device_private_entry(pmde))) {
>>>
>>>
>>
>> Klara, could you try with this change and see if it fixes the build?
>>
>> Thanks, Lance
> 
> This does indeed make it build.

Good to know, thanks for testing!

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling
  2026-07-01 16:46       ` Klara Modin
  2026-07-02  1:47         ` Lance Yang
@ 2026-07-02 17:49         ` Lorenzo Stoakes
  1 sibling, 0 replies; 9+ messages in thread
From: Lorenzo Stoakes @ 2026-07-02 17:49 UTC (permalink / raw)
  To: Klara Modin
  Cc: Lance Yang, david, richard.weiyang, akpm, riel, liam, vbabka,
	harry, jannh, balbirs, sj, ziy, linux-mm, linux-kernel, stable

On Wed, Jul 01, 2026 at 06:46:27PM +0200, Klara Modin wrote:
> On 2026-07-02 00:33:56 +0800, Lance Yang wrote:
> >
> > On Wed, Jul 01, 2026 at 05:36:33PM +0200, David Hildenbrand (Arm) wrote:
> > >On 7/1/26 16:33, Klara Modin wrote:
> > >> Hi,
> >
> > Hi,
> >
> > [...]
> > >>
> > >> This results in a build bug for my Raspberry Pi 1:
> >
> > Thanks for reporting this!
> >
> > >>  In file included from <command-line>:
> > >>  In function ‘check_pmd’,
> > >>      inlined from ‘page_vma_mapped_walk’ at /home/klara/git/linux/trees/bisect/mm/page_vma_mapped.c:256:10:
> > >>  /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:702:45: error: call to ‘__compiletime_assert_433’ declared with attribute error: BUILD_BUG failed
> > >>    702 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
> > >>        |                                             ^
> > >>  /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:683:25: note: in definition of macro ‘__compiletime_assert’
> > >>    683 |                         prefix ## suffix();                             \
> > >>        |                         ^~~~~~
> > >>  /home/klara/git/linux/trees/bisect/include/linux/compiler_types.h:702:9: note: in expansion of macro ‘_compiletime_assert’
> > >>    702 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
> > >>        |         ^~~~~~~~~~~~~~~~~~~
> > >>  /home/klara/git/linux/trees/bisect/include/linux/build_bug.h:40:37: note: in expansion of macro ‘compiletime_assert’
> > >>     40 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> > >>        |                                     ^~~~~~~~~~~~~~~~~~
> > >>  /home/klara/git/linux/trees/bisect/include/linux/build_bug.h:60:21: note: in expansion of macro ‘BUILD_BUG_ON_MSG’
> > >>     60 | #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> > >>        |                     ^~~~~~~~~~~~~~~~
> > >>  /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:113:28: note: in expansion of macro ‘BUILD_BUG’
> > >>    113 | #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
> > >>        |                            ^~~~~~~~~
> > >>  /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:117:26: note: in expansion of macro ‘HPAGE_PMD_SHIFT’
> > >>    117 | #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
> > >>        |                          ^~~~~~~~~~~~~~~
> > >>  /home/klara/git/linux/trees/bisect/include/linux/huge_mm.h:118:26: note: in expansion of macro ‘HPAGE_PMD_ORDER’
> > >>    118 | #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
> > >>        |                          ^~~~~~~~~~~~~~~
> > >>  /home/klara/git/linux/trees/bisect/mm/page_vma_mapped.c:142:20: note: in expansion of macro ‘HPAGE_PMD_NR’
> > >>    142 |         if ((pfn + HPAGE_PMD_NR - 1) < pvmw->pfn)
> > >>        |                    ^~~~~~~~~~~~
> > >>
> > >> bisect log:
> > >>
> > >>  # bad: [be5c93fa674f0fc3c8f359c2143abce6bbb422e6] Add linux-next specific files for 20260630
> > >>  git bisect start 'HEAD'
> > >>  # status: waiting for 'good' commit(s), 'bad' commit known
> > >>  # good: [dc59e4fea9d83f03bad6bddf3fa2e52491777482] Linux 7.2-rc1
> > >>  git bisect good dc59e4fea9d83f03bad6bddf3fa2e52491777482
> > >>  # bad: [6148219e90732fd06f5d7a498bda974e6a43ab4b] Merge branch 'nand/next' of https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git
> > >>  git bisect bad 6148219e90732fd06f5d7a498bda974e6a43ab4b
> > >>  # bad: [e0326ebe10191447ab8fa2e904080df7b743765e] Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
> > >>  git bisect bad e0326ebe10191447ab8fa2e904080df7b743765e
> > >>  # bad: [fbc9c5ac47cef5a2b04aef30c8e990b32dcf2548] Merge branch 'hwmon' of https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
> > >>  git bisect bad fbc9c5ac47cef5a2b04aef30c8e990b32dcf2548
> > >>  # bad: [e488171f6f6df6fc899a355079665fdb3c50b0e3] Merge branch 'for-linus' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
> > >>  git bisect bad e488171f6f6df6fc899a355079665fdb3c50b0e3
> > >>  # bad: [60db0fcb8fc9d80ac0b63041c632b41a311a45f1] Merge branch 'fs-current' of linux-next
> > >>  git bisect bad 60db0fcb8fc9d80ac0b63041c632b41a311a45f1
> > >>  # good: [51021d260d682aa17b3533848a99160ab83e0c93] Merge branch 'vfs.fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
> > >>  git bisect good 51021d260d682aa17b3533848a99160ab83e0c93
> > >>  # good: [ded56474db6552260786a65898322464b72c7540] mm: a second pagecache maintainer
> > >>  git bisect good ded56474db6552260786a65898322464b72c7540
> > >>  # good: [6c893b948351d42cfc3761cc746ab5b3d03ee7f3] Merge branch 'misc-7.2' into next-fixes
> > >>  git bisect good 6c893b948351d42cfc3761cc746ab5b3d03ee7f3
> > >>  # good: [bfcc55a14179495b0c41408908fd7b9d7785c694] lib: test_hmm: use device devt for coherent device range selection
> > >>  git bisect good bfcc55a14179495b0c41408908fd7b9d7785c694
> > >>  # good: [a27318567c92ba5482906d047e71a7aa4fd01889] Merge branch 'fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git
> > >>  git bisect good a27318567c92ba5482906d047e71a7aa4fd01889
> > >>  # bad: [6887a39652cdfd4cfd3b0962662c9cbc26ce5252] mm/page_vma_mapped: fix device-private PMD handling
> > >>  git bisect bad 6887a39652cdfd4cfd3b0962662c9cbc26ce5252
> > >>  # good: [2cc6bd0efc264b9ac760c2bc74dff4f521a680a1] MAINTAINERS: s/SeongJae/SJ/
> > >>  git bisect good 2cc6bd0efc264b9ac760c2bc74dff4f521a680a1
> > >>  # first 'bad' commit: [6887a39652cdfd4cfd3b0962662c9cbc26ce5252] mm/page_vma_mapped: fix device-private PMD handling
> > >>
> > >>>
> > >>> Fixes: 65edfda6f3f2 ("mm/rmap: extend rmap and migration support device-private entries")
> > >>> Cc: <stable@vger.kernel.org>
> > >>> Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
> > >>> Suggested-by: David Hildenbrand <david@kernel.org>
> > >>> Cc: David Hildenbrand <david@kernel.org>
> > >>> Cc: Balbir Singh <balbirs@nvidia.com>
> > >>> Cc: SeongJae Park <sj@kernel.org>
> > >>> Cc: Zi Yan <ziy@nvidia.com>
> > >>> Cc: Lorenzo Stoakes <ljs@kernel.org>
> > >>> Cc: Lance Yang <lance.yang@linux.dev>
> > >>>
> > >>> ---
> > >>> v5:
> > >>>   * put device-private pmd handling along with the other two cases
> > >>>   * remove thp_migration_supported()
> > >>> v4: https://lore.kernel.org/all/20260624065353.1622-1-richard.weiyang@gmail.com/T/#u
> > >>>   * refine subject and commit log based on Lorenzo's suggestion
> > >>>   * put pmd device-private entry handling in its own if branch,
> > >>>     suggested by Lorenzo
> > >>>
> > >>> v3:
> > >>>   * remove cleanup part, only fix the issue for device-private entry
> > >>>   * refine user effect description based on Lorenzo's suggestion
> > >>>
> > >>> v2: https://lore.kernel.org/all/20260616063436.20455-1-richard.weiyang@gmail.com/T/#u
> > >>>   * specify the possible error case of current code and user visible effect
> > >>>   * besides fix, cleanup the pmd entry handling based on David's suggestion
> > >>>
> > >>> v1: https://lore.kernel.org/linux-mm/20260508013728.21285-1-richard.weiyang@gmail.com/
> > >>> ---
> > >>>  mm/page_vma_mapped.c | 30 ++++++++++++++++--------------
> > >>>  1 file changed, 16 insertions(+), 14 deletions(-)
> > >>>
> > >>> diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
> > >>> index 2ccbabfb2cc1..2d6c58488e3a 100644
> > >>> --- a/mm/page_vma_mapped.c
> > >>> +++ b/mm/page_vma_mapped.c
> > >>> @@ -243,21 +243,30 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
> > >>>  		 */
> > >>>  		pmde = pmdp_get_lockless(pvmw->pmd);
> > >>>
> > >>> -		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde)) {
> > >>> +		if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
> > >>> +		    pmd_is_device_private_entry(pmde)) {
> > >>>  			pvmw->ptl = pmd_lock(mm, pvmw->pmd);
> > >>>  			pmde = *pvmw->pmd;
> > >>> -			if (!pmd_present(pmde)) {
> > >>> +			if (pmd_is_migration_entry(pmde)) {
> > >>>  				softleaf_t entry;
> > >>>
> > >>> -				if (!thp_migration_supported() ||
> > >>> -				    !(pvmw->flags & PVMW_MIGRATION))
> > >>> +				if (!(pvmw->flags & PVMW_MIGRATION))
> > >>>  					return not_found(pvmw);
> > >>>  				entry = softleaf_from_pmd(pmde);
> > >>> +				if (!check_pmd(softleaf_to_pfn(entry), pvmw))
> > >>> +					return not_found(pvmw);
> > >>> +				return true;
> > >>> +			} else if (pmd_is_device_private_entry(pmde)) {
> > >>> +				softleaf_t entry;
> > >>>
> > >>
> > >>> -				if (!softleaf_is_migration(entry) ||
> > >>> -				    !check_pmd(softleaf_to_pfn(entry), pvmw))
> > >>
> > >> My only guess here would be that the compiler evaluates
> > >> !softleaf_is_migration(entry) to always be true and optimises away the
> > >> !check_pmd(softleaf_to_pfn(entry), pvmw) which is why this worked
> > >> before?
> > >
> > >Weird, we enter this path only with
> > >
> > >pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
> > >pmd_is_device_private_entry(pmde)
> > >
> > >If any one of these would compile for !CONFIG_TRANSPARENT_HUGEPAGE that would be
> > >odd.
> > >
> > >pmd_is_device_private_entry() is hard-coded to false unless
> > >CONFIG_ARCH_ENABLE_THP_MIGRATION. Which is only selected with
> > >ARCH_ENABLE_THP_MIGRATION.
> > >
> > >pmd_trans_huge() as well.
> > >
> > >Maybe it's struggling with pmd_is_migration_entry() on some (older) compilers?
> > >(not innlining stuff and not properly optimizing it out).
>
> It's a GCC 16 cross-compiler for armv6 so I wouldn't call it old :)
>
> > >
> > >The whole conditional must be optimized out.
> >
> > Right. Kinda weird if compiler didn't fold
> >
> > pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
> > pmd_is_device_private_entry(pmde)
> >
> > away here ...
> >
> > >We could check for IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) right at the start
> > >to make it easier for the compiler:
> >
> > +1, explicit THP guard should do the trick :)
> >
> > >if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) &&
> > >    (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
> > >     pmd_is_device_private_entry(pmde))) {
> > >
> > >
> >
> > Klara, could you try with this change and see if it fixes the build?
> >
> > Thanks, Lance
>
> This does indeed make it build.

Hmm this is pretty ugly though.

softleaf_is_migration() is a bit-test so I don't think that's the issue.

I think the issue here is thp_migration_supported() that's what's needed here.

So maybe

-				if (!thp_migration_supported() ||
-				    !(pvmw->flags & PVMW_MIGRATION))
+				if (!(pvmw->flags & PVMW_MIGRATION))

Should just be kept as it is or:


+#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
 static inline bool pmd_is_migration_entry(pmd_t pmd)
 {
      return softleaf_is_migration(softleaf_from_pmd(pmd));
 }
+#else
+static inline bool pmd_is_migration_entry(pmd_t pmd)
+{
+     return false;
+}
+#endif

And I think the CONFIG_TRANSPARENT_HUGEPAGE is just conflating the
CONFIG_ARCH_ENABLE_THP_MIGRATION.



>
> Thanks,
> Klara Modin

Thanks, Lorenzo

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-07-02 17:49 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-30  2:15 [Patch mm-hotfixes v5] mm/page_vma_mapped: fix device-private PMD handling Wei Yang
2026-06-30  2:43 ` Lance Yang
2026-06-30  3:57 ` Balbir Singh
2026-07-01 14:33 ` Klara Modin
2026-07-01 15:36   ` David Hildenbrand (Arm)
2026-07-01 16:33     ` Lance Yang
2026-07-01 16:46       ` Klara Modin
2026-07-02  1:47         ` Lance Yang
2026-07-02 17:49         ` Lorenzo Stoakes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox