* [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