* [PATCH v2 0/2] mm: folio conversion and refactoring in do_swap_page()
@ 2026-07-23 3:07 Hongfu Li
2026-07-23 3:07 ` [PATCH v2 1/2] mm: Use a folio in the softleaf_is_device_private path Hongfu Li
2026-07-23 3:07 ` [PATCH v2 2/2] mm: Extract non-swap page handling to do_non_swap_page() Hongfu Li
0 siblings, 2 replies; 9+ messages in thread
From: Hongfu Li @ 2026-07-23 3:07 UTC (permalink / raw)
To: akpm, david, ljs, liam, vbabka, rppt, surenb, mhocko
Cc: linux-mm, linux-kernel, hongfu.li, Hongfu Li
From: Hongfu Li <lihongfu@kylinos.cn>
Convert the device-private migration path in do_swap_page() to use
folio APIs, then extract all non-swap entry handling into a new
do_non_swap_page() helper to improve readability and reduce the
size of the main swap fault function.
Hongfu Li (2):
mm: Use a folio in the softleaf_is_device_private path
mm: Extract non-swap page handling to do_non_swap_page()
mm/memory.c | 119 ++++++++++++++++++++++++++++++----------------------
1 file changed, 69 insertions(+), 50 deletions(-)
---
v2:
- Drop fault_folio, reuse the existing folio variable instead
- Refresh commit messages
- Update comment to use "folio" instead of "page" in the
device_private path
- Add Acked-by: David Hildenbrand
- Add patch 2/2 to extract do_non_swap_page() from do_swap_page()
- Link to v1: https://lore.kernel.org/all/20260721013347.65698-1-hongfu.li@linux.dev/
--
2.54.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/2] mm: Use a folio in the softleaf_is_device_private path
2026-07-23 3:07 [PATCH v2 0/2] mm: folio conversion and refactoring in do_swap_page() Hongfu Li
@ 2026-07-23 3:07 ` Hongfu Li
2026-07-27 16:29 ` Lorenzo Stoakes (ARM)
2026-07-23 3:07 ` [PATCH v2 2/2] mm: Extract non-swap page handling to do_non_swap_page() Hongfu Li
1 sibling, 1 reply; 9+ messages in thread
From: Hongfu Li @ 2026-07-23 3:07 UTC (permalink / raw)
To: akpm, david, ljs, liam, vbabka, rppt, surenb, mhocko
Cc: linux-mm, linux-kernel, hongfu.li, Hongfu Li
From: Hongfu Li <lihongfu@kylinos.cn>
Use the folio APIs in the device_private migration path of do_swap_page(),
replacing four calls to compound_head() with one.
Signed-off-by: Hongfu Li <lihongfu@kylinos.cn>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
---
mm/memory.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c
index d5e87624f692..ae521baa8c84 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4871,18 +4871,19 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
goto unlock;
/*
- * Get a page reference while we know the page can't be
+ * Get a folio reference while we know the folio can't be
* freed.
*/
- if (trylock_page(vmf->page)) {
+ folio = page_folio(vmf->page);
+ if (folio_trylock(folio)) {
struct dev_pagemap *pgmap;
- get_page(vmf->page);
+ folio_get(folio);
pte_unmap_unlock(vmf->pte, vmf->ptl);
pgmap = page_pgmap(vmf->page);
ret = pgmap->ops->migrate_to_ram(vmf);
- unlock_page(vmf->page);
- put_page(vmf->page);
+ folio_unlock(folio);
+ folio_put(folio);
} else {
pte_unmap(vmf->pte);
softleaf_entry_wait_on_locked(entry, vmf->ptl);
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/2] mm: Extract non-swap page handling to do_non_swap_page()
2026-07-23 3:07 [PATCH v2 0/2] mm: folio conversion and refactoring in do_swap_page() Hongfu Li
2026-07-23 3:07 ` [PATCH v2 1/2] mm: Use a folio in the softleaf_is_device_private path Hongfu Li
@ 2026-07-23 3:07 ` Hongfu Li
2026-07-24 19:33 ` David Hildenbrand (Arm)
2026-07-27 16:30 ` Lorenzo Stoakes (ARM)
1 sibling, 2 replies; 9+ messages in thread
From: Hongfu Li @ 2026-07-23 3:07 UTC (permalink / raw)
To: akpm, david, ljs, liam, vbabka, rppt, surenb, mhocko
Cc: linux-mm, linux-kernel, hongfu.li, Hongfu Li
From: Hongfu Li <lihongfu@kylinos.cn>
Factor non-swap entry logic out of bloated do_swap_page() to simplify
the main swap fault flow and improve readability.
The new do_non_swap_page() handles migration, device private/exclusive,
hwpoison, marker and bad PTE entries.
Signed-off-by: Hongfu Li <lihongfu@kylinos.cn>
---
mm/memory.c | 120 ++++++++++++++++++++++++++++++----------------------
1 file changed, 69 insertions(+), 51 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c
index ae521baa8c84..50d8e92aef91 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4815,6 +4815,74 @@ static void check_swap_exclusive(struct folio *folio, swp_entry_t entry,
} while (--nr_pages);
}
+static vm_fault_t do_non_swap_page(struct vm_fault *vmf)
+{
+ struct vm_area_struct *vma = vmf->vma;
+ struct folio *folio;
+ softleaf_t entry;
+ vm_fault_t ret = 0;
+
+ entry = softleaf_from_pte(vmf->orig_pte);
+ if (softleaf_is_migration(entry)) {
+ migration_entry_wait(vma->vm_mm, vmf->pmd,
+ vmf->address);
+ } else if (softleaf_is_device_exclusive(entry)) {
+ vmf->page = softleaf_to_page(entry);
+ ret = remove_device_exclusive_entry(vmf);
+ } else if (softleaf_is_device_private(entry)) {
+
+ if (vmf->flags & FAULT_FLAG_VMA_LOCK) {
+ /*
+ * migrate_to_ram is not yet ready to operate
+ * under VMA lock.
+ */
+ vma_end_read(vma);
+ return VM_FAULT_RETRY;
+ }
+
+ vmf->page = softleaf_to_page(entry);
+ vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
+ vmf->address, &vmf->ptl);
+ if (unlikely(!vmf->pte ||
+ !pte_same(ptep_get(vmf->pte),
+ vmf->orig_pte)))
+ goto unlock;
+
+ /*
+ * Get a folio reference while we know the folio can't be
+ * freed.
+ */
+ folio = page_folio(vmf->page);
+ if (folio_trylock(folio)) {
+ struct dev_pagemap *pgmap;
+
+ folio_get(folio);
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ pgmap = page_pgmap(vmf->page);
+ ret = pgmap->ops->migrate_to_ram(vmf);
+ folio_unlock(folio);
+ folio_put(folio);
+ } else {
+ pte_unmap(vmf->pte);
+ softleaf_entry_wait_on_locked(entry, vmf->ptl);
+ }
+ } else if (softleaf_is_hwpoison(entry)) {
+ ret = VM_FAULT_HWPOISON;
+ } else if (softleaf_is_marker(entry)) {
+ ret = handle_pte_marker(vmf);
+ } else {
+ print_bad_pte(vma, vmf->address, vmf->orig_pte, NULL);
+ ret = VM_FAULT_SIGBUS;
+ }
+
+ return ret;
+
+unlock:
+ if (vmf->pte)
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ return ret;
+}
+
/*
* We enter with either the VMA lock or the mmap_lock held (see
* FAULT_FLAG_VMA_LOCK), and pte mapped but not yet locked.
@@ -4845,57 +4913,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
entry = softleaf_from_pte(vmf->orig_pte);
if (unlikely(!softleaf_is_swap(entry))) {
- if (softleaf_is_migration(entry)) {
- migration_entry_wait(vma->vm_mm, vmf->pmd,
- vmf->address);
- } else if (softleaf_is_device_exclusive(entry)) {
- vmf->page = softleaf_to_page(entry);
- ret = remove_device_exclusive_entry(vmf);
- } else if (softleaf_is_device_private(entry)) {
- if (vmf->flags & FAULT_FLAG_VMA_LOCK) {
- /*
- * migrate_to_ram is not yet ready to operate
- * under VMA lock.
- */
- vma_end_read(vma);
- ret = VM_FAULT_RETRY;
- goto out;
- }
-
- vmf->page = softleaf_to_page(entry);
- vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
- vmf->address, &vmf->ptl);
- if (unlikely(!vmf->pte ||
- !pte_same(ptep_get(vmf->pte),
- vmf->orig_pte)))
- goto unlock;
-
- /*
- * Get a folio reference while we know the folio can't be
- * freed.
- */
- folio = page_folio(vmf->page);
- if (folio_trylock(folio)) {
- struct dev_pagemap *pgmap;
-
- folio_get(folio);
- pte_unmap_unlock(vmf->pte, vmf->ptl);
- pgmap = page_pgmap(vmf->page);
- ret = pgmap->ops->migrate_to_ram(vmf);
- folio_unlock(folio);
- folio_put(folio);
- } else {
- pte_unmap(vmf->pte);
- softleaf_entry_wait_on_locked(entry, vmf->ptl);
- }
- } else if (softleaf_is_hwpoison(entry)) {
- ret = VM_FAULT_HWPOISON;
- } else if (softleaf_is_marker(entry)) {
- ret = handle_pte_marker(vmf);
- } else {
- print_bad_pte(vma, vmf->address, vmf->orig_pte, NULL);
- ret = VM_FAULT_SIGBUS;
- }
+ ret = do_non_swap_page(vmf);
goto out;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] mm: Extract non-swap page handling to do_non_swap_page()
2026-07-23 3:07 ` [PATCH v2 2/2] mm: Extract non-swap page handling to do_non_swap_page() Hongfu Li
@ 2026-07-24 19:33 ` David Hildenbrand (Arm)
2026-07-27 12:10 ` Hongfu Li
2026-07-27 16:30 ` Lorenzo Stoakes (ARM)
1 sibling, 1 reply; 9+ messages in thread
From: David Hildenbrand (Arm) @ 2026-07-24 19:33 UTC (permalink / raw)
To: Hongfu Li, akpm, ljs, liam, vbabka, rppt, surenb, mhocko
Cc: linux-mm, linux-kernel, Hongfu Li
On 7/23/26 05:07, Hongfu Li wrote:
> From: Hongfu Li <lihongfu@kylinos.cn>
>
> Factor non-swap entry logic out of bloated do_swap_page() to simplify
> the main swap fault flow and improve readability.
>
> The new do_non_swap_page() handles migration, device private/exclusive,
> hwpoison, marker and bad PTE entries.
>
> Signed-off-by: Hongfu Li <lihongfu@kylinos.cn>
> ---
> mm/memory.c | 120 ++++++++++++++++++++++++++++++----------------------
> 1 file changed, 69 insertions(+), 51 deletions(-)
>
> diff --git a/mm/memory.c b/mm/memory.c
> index ae521baa8c84..50d8e92aef91 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -4815,6 +4815,74 @@ static void check_swap_exclusive(struct folio *folio, swp_entry_t entry,
> } while (--nr_pages);
> }
>
> +static vm_fault_t do_non_swap_page(struct vm_fault *vmf)
We're handling softleaf entries that are not swap entries.
do_nonswap_softleaf() or sth like that would be better than talking about "page"
if there is not even a page.
But actually it should be the other way around:
do_softleaf_entry() [currently do_swap_page]
... non-swap entries
do_swap_entry()
Or sth like that. Then, maybe in the future, we can just move do_swap_entry()
out of memory.c
So we're factoring the wrong thing out in this patch.
--
Cheers,
David
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] mm: Extract non-swap page handling to do_non_swap_page()
2026-07-24 19:33 ` David Hildenbrand (Arm)
@ 2026-07-27 12:10 ` Hongfu Li
2026-07-27 12:16 ` David Hildenbrand (Arm)
0 siblings, 1 reply; 9+ messages in thread
From: Hongfu Li @ 2026-07-27 12:10 UTC (permalink / raw)
To: david
Cc: akpm, hongfu.li, liam, lihongfu, linux-kernel, linux-mm, ljs,
mhocko, rppt, surenb, vbabka
> > mm/memory.c | 120 ++++++++++++++++++++++++++++++----------------------
> > 1 file changed, 69 insertions(+), 51 deletions(-)
> >
> > diff --git a/mm/memory.c b/mm/memory.c
> > index ae521baa8c84..50d8e92aef91 100644
> > --- a/mm/memory.c
> > +++ b/mm/memory.c
> > @@ -4815,6 +4815,74 @@ static void check_swap_exclusive(struct folio *folio, swp_entry_t entry,
> > } while (--nr_pages);
> > }
> >
> > +static vm_fault_t do_non_swap_page(struct vm_fault *vmf)
>
> We're handling softleaf entries that are not swap entries.
>
> do_nonswap_softleaf() or sth like that would be better than talking about "page"
> if there is not even a page.
>
> But actually it should be the other way around:
>
> do_softleaf_entry() [currently do_swap_page]
> ... non-swap entries
> do_swap_entry()
>
> Or sth like that. Then, maybe in the future, we can just move do_swap_entry()
> out of memory.c
>
> So we're factoring the wrong thing out in this patch.
Thank you very much for the detailed review, your analysis makes perfect sense to me.
I'm glad to send out v3 shortly for your further review, with
do_non_swap_page renamed to do_nonswap_softleaf.
Best regards,
Hongfu
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] mm: Extract non-swap page handling to do_non_swap_page()
2026-07-27 12:10 ` Hongfu Li
@ 2026-07-27 12:16 ` David Hildenbrand (Arm)
2026-07-27 13:58 ` Lorenzo Stoakes (ARM)
0 siblings, 1 reply; 9+ messages in thread
From: David Hildenbrand (Arm) @ 2026-07-27 12:16 UTC (permalink / raw)
To: Hongfu Li
Cc: akpm, liam, lihongfu, linux-kernel, linux-mm, ljs, mhocko, rppt,
surenb, vbabka
On 7/27/26 14:10, Hongfu Li wrote:
>>> mm/memory.c | 120 ++++++++++++++++++++++++++++++----------------------
>>> 1 file changed, 69 insertions(+), 51 deletions(-)
>>>
>>> diff --git a/mm/memory.c b/mm/memory.c
>>> index ae521baa8c84..50d8e92aef91 100644
>>> --- a/mm/memory.c
>>> +++ b/mm/memory.c
>>> @@ -4815,6 +4815,74 @@ static void check_swap_exclusive(struct folio *folio, swp_entry_t entry,
>>> } while (--nr_pages);
>>> }
>>>
>>> +static vm_fault_t do_non_swap_page(struct vm_fault *vmf)
>>
>> We're handling softleaf entries that are not swap entries.
>>
>> do_nonswap_softleaf() or sth like that would be better than talking about "page"
>> if there is not even a page.
>>
>> But actually it should be the other way around:
>>
>> do_softleaf_entry() [currently do_swap_page]
>> ... non-swap entries
>> do_swap_entry()
>>
>> Or sth like that. Then, maybe in the future, we can just move do_swap_entry()
>> out of memory.c
>>
>> So we're factoring the wrong thing out in this patch.
>
> Thank you very much for the detailed review, your analysis makes perfect sense to me.
>
> I'm glad to send out v3 shortly for your further review, with
> do_non_swap_page renamed to do_nonswap_softleaf.
Read again, that's not what I meant.
--
Cheers,
David
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] mm: Extract non-swap page handling to do_non_swap_page()
2026-07-27 12:16 ` David Hildenbrand (Arm)
@ 2026-07-27 13:58 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 9+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-07-27 13:58 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: Hongfu Li, akpm, liam, lihongfu, linux-kernel, linux-mm, mhocko,
rppt, surenb, vbabka
On Mon, Jul 27, 2026 at 02:16:40PM +0200, David Hildenbrand (Arm) wrote:
> On 7/27/26 14:10, Hongfu Li wrote:
> >>> mm/memory.c | 120 ++++++++++++++++++++++++++++++----------------------
> >>> 1 file changed, 69 insertions(+), 51 deletions(-)
> >>>
> >>> diff --git a/mm/memory.c b/mm/memory.c
> >>> index ae521baa8c84..50d8e92aef91 100644
> >>> --- a/mm/memory.c
> >>> +++ b/mm/memory.c
> >>> @@ -4815,6 +4815,74 @@ static void check_swap_exclusive(struct folio *folio, swp_entry_t entry,
> >>> } while (--nr_pages);
> >>> }
> >>>
> >>> +static vm_fault_t do_non_swap_page(struct vm_fault *vmf)
> >>
> >> We're handling softleaf entries that are not swap entries.
> >>
> >> do_nonswap_softleaf() or sth like that would be better than talking about "page"
> >> if there is not even a page.
> >>
> >> But actually it should be the other way around:
> >>
> >> do_softleaf_entry() [currently do_swap_page]
> >> ... non-swap entries
> >> do_swap_entry()
> >>
> >> Or sth like that. Then, maybe in the future, we can just move do_swap_entry()
> >> out of memory.c
> >>
> >> So we're factoring the wrong thing out in this patch.
> >
> > Thank you very much for the detailed review, your analysis makes perfect sense to me.
> >
> > I'm glad to send out v3 shortly for your further review, with
> > do_non_swap_page renamed to do_nonswap_softleaf.
>
> Read again, that's not what I meant.
Yeah please do NOT introduce 'nonswap' we already had fun with the nonswap swap
entry before :)
Quoting David:
do_softleaf_entry() [currently do_swap_page]
... non-swap entries
do_swap_entry()
Also, swap entries _are_ softleaf entries.
The whole point of the softleaf change/renaming was to differentiate page
table entries that are purely there for mapping stuff from the hardware's
point of view (non-present because nothing is mapped there, present if
mapping something) vs. something non-present because the entry is
software-defined (hence SOFT-leaf).
Swap entries are software-defined and thus fall into category.
You can see all of the softleaf types trivially in include/linux/leafops.h
in enum softleaf_type:
enum softleaf_type {
/* Fundamental types. */
SOFTLEAF_NONE,
SOFTLEAF_SWAP,
/* Migration types. */
SOFTLEAF_MIGRATION_READ,
SOFTLEAF_MIGRATION_READ_EXCLUSIVE,
SOFTLEAF_MIGRATION_WRITE,
/* Device types. */
SOFTLEAF_DEVICE_PRIVATE_READ,
SOFTLEAF_DEVICE_PRIVATE_WRITE,
SOFTLEAF_DEVICE_EXCLUSIVE,
/* H/W posion types. */
SOFTLEAF_HWPOISON,
/* Marker types. */
SOFTLEAF_MARKER,
};
>
> --
> Cheers,
>
> David
Cheers, Lorenzo
P.S. I do remember suggesting that you _slow down_ :) we are into the quiet
period now so let's maybe reduce the pace of series + respins, thanks.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/2] mm: Use a folio in the softleaf_is_device_private path
2026-07-23 3:07 ` [PATCH v2 1/2] mm: Use a folio in the softleaf_is_device_private path Hongfu Li
@ 2026-07-27 16:29 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 9+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-07-27 16:29 UTC (permalink / raw)
To: Hongfu Li
Cc: akpm, david, liam, vbabka, rppt, surenb, mhocko, linux-mm,
linux-kernel, Hongfu Li
On Thu, Jul 23, 2026 at 11:07:51AM +0800, Hongfu Li wrote:
> From: Hongfu Li <lihongfu@kylinos.cn>
>
> Use the folio APIs in the device_private migration path of do_swap_page(),
> replacing four calls to compound_head() with one.
>
> Signed-off-by: Hongfu Li <lihongfu@kylinos.cn>
> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
With changes below applied LGTM, so:
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> mm/memory.c | 11 ++++++-----
> 1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/mm/memory.c b/mm/memory.c
> index d5e87624f692..ae521baa8c84 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -4871,18 +4871,19 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
> goto unlock;
>
Up here we have:
vmf->page = softleaf_to_page(entry);
vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
vmf->address, &vmf->ptl);
if (unlikely(!vmf->pte ||
!pte_same(ptep_get(vmf->pte),
vmf->orig_pte)))
Since we're canonicalising to folio why not actually set folio using
softleaf_to_folio()?
So
+ folio = softleaf_to_folio(entry);
- vmf->page = softleaf_to_page(entry);
+ vmf->page = &folio->page;
This would also make more sense in your 2/2. But more on that in a sec.
> /*
> - * Get a page reference while we know the page can't be
> + * Get a folio reference while we know the folio can't be
NIT: be -> next line for 80 chars.
> * freed.
> */
> - if (trylock_page(vmf->page)) {
> + folio = page_folio(vmf->page);
> + if (folio_trylock(folio)) {
> struct dev_pagemap *pgmap;
>
> - get_page(vmf->page);
> + folio_get(folio);
> pte_unmap_unlock(vmf->pte, vmf->ptl);
> pgmap = page_pgmap(vmf->page);
> ret = pgmap->ops->migrate_to_ram(vmf);
> - unlock_page(vmf->page);
> - put_page(vmf->page);
> + folio_unlock(folio);
> + folio_put(folio);
> } else {
> pte_unmap(vmf->pte);
> softleaf_entry_wait_on_locked(entry, vmf->ptl);
> --
> 2.54.0
>
Thanks, Lorenzo
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] mm: Extract non-swap page handling to do_non_swap_page()
2026-07-23 3:07 ` [PATCH v2 2/2] mm: Extract non-swap page handling to do_non_swap_page() Hongfu Li
2026-07-24 19:33 ` David Hildenbrand (Arm)
@ 2026-07-27 16:30 ` Lorenzo Stoakes (ARM)
1 sibling, 0 replies; 9+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-07-27 16:30 UTC (permalink / raw)
To: Hongfu Li
Cc: akpm, david, liam, vbabka, rppt, surenb, mhocko, linux-mm,
linux-kernel, Hongfu Li
On Thu, Jul 23, 2026 at 11:07:52AM +0800, Hongfu Li wrote:
> From: Hongfu Li <lihongfu@kylinos.cn>
>
> Factor non-swap entry logic out of bloated do_swap_page() to simplify
> the main swap fault flow and improve readability.
>
> The new do_non_swap_page() handles migration, device private/exclusive,
> hwpoison, marker and bad PTE entries.
>
> Signed-off-by: Hongfu Li <lihongfu@kylinos.cn>
We've already gone over this elsewhere in the thread, we don't want a
do_non_swap_page() (HELL no).
But in general I want to finish what I started with softleaves, which still has
some work to do with swap entries so maybe could you just drop this patch so I
can follow up with that later?
That way you can do a respin of just the 1/2 as a v3.
Thanks, Lorenzo
> ---
> mm/memory.c | 120 ++++++++++++++++++++++++++++++----------------------
> 1 file changed, 69 insertions(+), 51 deletions(-)
>
> diff --git a/mm/memory.c b/mm/memory.c
> index ae521baa8c84..50d8e92aef91 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -4815,6 +4815,74 @@ static void check_swap_exclusive(struct folio *folio, swp_entry_t entry,
> } while (--nr_pages);
> }
>
> +static vm_fault_t do_non_swap_page(struct vm_fault *vmf)
> +{
> + struct vm_area_struct *vma = vmf->vma;
> + struct folio *folio;
> + softleaf_t entry;
> + vm_fault_t ret = 0;
> +
> + entry = softleaf_from_pte(vmf->orig_pte);
> + if (softleaf_is_migration(entry)) {
> + migration_entry_wait(vma->vm_mm, vmf->pmd,
> + vmf->address);
> + } else if (softleaf_is_device_exclusive(entry)) {
> + vmf->page = softleaf_to_page(entry);
> + ret = remove_device_exclusive_entry(vmf);
> + } else if (softleaf_is_device_private(entry)) {
> +
> + if (vmf->flags & FAULT_FLAG_VMA_LOCK) {
> + /*
> + * migrate_to_ram is not yet ready to operate
> + * under VMA lock.
> + */
> + vma_end_read(vma);
> + return VM_FAULT_RETRY;
> + }
> +
> + vmf->page = softleaf_to_page(entry);
> + vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
> + vmf->address, &vmf->ptl);
> + if (unlikely(!vmf->pte ||
> + !pte_same(ptep_get(vmf->pte),
> + vmf->orig_pte)))
> + goto unlock;
> +
> + /*
> + * Get a folio reference while we know the folio can't be
> + * freed.
> + */
> + folio = page_folio(vmf->page);
> + if (folio_trylock(folio)) {
> + struct dev_pagemap *pgmap;
> +
> + folio_get(folio);
> + pte_unmap_unlock(vmf->pte, vmf->ptl);
> + pgmap = page_pgmap(vmf->page);
> + ret = pgmap->ops->migrate_to_ram(vmf);
> + folio_unlock(folio);
> + folio_put(folio);
> + } else {
> + pte_unmap(vmf->pte);
> + softleaf_entry_wait_on_locked(entry, vmf->ptl);
> + }
> + } else if (softleaf_is_hwpoison(entry)) {
> + ret = VM_FAULT_HWPOISON;
> + } else if (softleaf_is_marker(entry)) {
> + ret = handle_pte_marker(vmf);
> + } else {
> + print_bad_pte(vma, vmf->address, vmf->orig_pte, NULL);
> + ret = VM_FAULT_SIGBUS;
> + }
> +
> + return ret;
> +
> +unlock:
> + if (vmf->pte)
> + pte_unmap_unlock(vmf->pte, vmf->ptl);
> + return ret;
> +}
> +
> /*
> * We enter with either the VMA lock or the mmap_lock held (see
> * FAULT_FLAG_VMA_LOCK), and pte mapped but not yet locked.
> @@ -4845,57 +4913,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
>
> entry = softleaf_from_pte(vmf->orig_pte);
> if (unlikely(!softleaf_is_swap(entry))) {
> - if (softleaf_is_migration(entry)) {
> - migration_entry_wait(vma->vm_mm, vmf->pmd,
> - vmf->address);
> - } else if (softleaf_is_device_exclusive(entry)) {
> - vmf->page = softleaf_to_page(entry);
> - ret = remove_device_exclusive_entry(vmf);
> - } else if (softleaf_is_device_private(entry)) {
> - if (vmf->flags & FAULT_FLAG_VMA_LOCK) {
> - /*
> - * migrate_to_ram is not yet ready to operate
> - * under VMA lock.
> - */
> - vma_end_read(vma);
> - ret = VM_FAULT_RETRY;
> - goto out;
> - }
> -
> - vmf->page = softleaf_to_page(entry);
> - vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
> - vmf->address, &vmf->ptl);
> - if (unlikely(!vmf->pte ||
> - !pte_same(ptep_get(vmf->pte),
> - vmf->orig_pte)))
> - goto unlock;
> -
> - /*
> - * Get a folio reference while we know the folio can't be
> - * freed.
> - */
> - folio = page_folio(vmf->page);
> - if (folio_trylock(folio)) {
> - struct dev_pagemap *pgmap;
> -
> - folio_get(folio);
> - pte_unmap_unlock(vmf->pte, vmf->ptl);
> - pgmap = page_pgmap(vmf->page);
> - ret = pgmap->ops->migrate_to_ram(vmf);
> - folio_unlock(folio);
> - folio_put(folio);
> - } else {
> - pte_unmap(vmf->pte);
> - softleaf_entry_wait_on_locked(entry, vmf->ptl);
> - }
> - } else if (softleaf_is_hwpoison(entry)) {
> - ret = VM_FAULT_HWPOISON;
> - } else if (softleaf_is_marker(entry)) {
> - ret = handle_pte_marker(vmf);
> - } else {
> - print_bad_pte(vma, vmf->address, vmf->orig_pte, NULL);
> - ret = VM_FAULT_SIGBUS;
> - }
> + ret = do_non_swap_page(vmf);
> goto out;
> }
>
> --
> 2.54.0
>
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-07-27 16:31 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-23 3:07 [PATCH v2 0/2] mm: folio conversion and refactoring in do_swap_page() Hongfu Li
2026-07-23 3:07 ` [PATCH v2 1/2] mm: Use a folio in the softleaf_is_device_private path Hongfu Li
2026-07-27 16:29 ` Lorenzo Stoakes (ARM)
2026-07-23 3:07 ` [PATCH v2 2/2] mm: Extract non-swap page handling to do_non_swap_page() Hongfu Li
2026-07-24 19:33 ` David Hildenbrand (Arm)
2026-07-27 12:10 ` Hongfu Li
2026-07-27 12:16 ` David Hildenbrand (Arm)
2026-07-27 13:58 ` Lorenzo Stoakes (ARM)
2026-07-27 16:30 ` Lorenzo Stoakes (ARM)
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.