* [RFC PATCH 0/3] Some remote_vm folio conversions
@ 2025-06-25 17:48 Vishal Moola (Oracle)
2025-06-25 17:48 ` [RFC PATCH 1/3] mm/memory.c: convert __copy_remote_vm_str() to folios Vishal Moola (Oracle)
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Vishal Moola (Oracle) @ 2025-06-25 17:48 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Matthew Wilcox (Oracle), David Hildenbrand,
Jordan Rome, Andrew Morton, Vishal Moola (Oracle)
Both callers of unmap_and_put_page() are for tracing purposes and
interact with user vmas. In a memdesc world, these should end up
operating on folios, so convert them.
This patchset converts those functions so that gup - namely
get_user_page_vma_remote() - can eventually safely pass around
large folios.
This iteration does NOT allow support for handling a large folio all at
once, it merely makes working on subpages of a large folio safe. Does
anyone have any thoughts on if we might want to handle these in larger
than PAGE_SIZE chunks? It seems like a lot of work with how kmap()
works right now...
On a similar note, might we want to convert implementations of
copy_{to,from}_user_page() to pass around folios as well?
Vishal Moola (Oracle) (3):
mm/memory.c: convert __copy_remote_vm_str() to folios
mm/memory.c: convert __access_remote_vm() to folios
mm: Remove unmap_and_put_page()
include/linux/highmem.h | 6 -----
mm/memory.c | 52 +++++++++++++++++++++++++----------------
2 files changed, 32 insertions(+), 26 deletions(-)
--
2.49.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC PATCH 1/3] mm/memory.c: convert __copy_remote_vm_str() to folios
2025-06-25 17:48 [RFC PATCH 0/3] Some remote_vm folio conversions Vishal Moola (Oracle)
@ 2025-06-25 17:48 ` Vishal Moola (Oracle)
2025-06-25 18:00 ` Matthew Wilcox
2025-06-25 17:48 ` [RFC PATCH 2/3] mm/memory.c: convert __access_remote_vm() " Vishal Moola (Oracle)
2025-06-25 17:48 ` [RFC PATCH 3/3] mm: Remove unmap_and_put_page() Vishal Moola (Oracle)
2 siblings, 1 reply; 9+ messages in thread
From: Vishal Moola (Oracle) @ 2025-06-25 17:48 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Matthew Wilcox (Oracle), David Hildenbrand,
Jordan Rome, Andrew Morton, Vishal Moola (Oracle)
Use kmap_local_folio() instead of kmap_local_page().
Replaces 2 calls to compound_head() from unmap_and_put_page() with one.
This prepares us for the removal of unmap_and_put_page(), and helps
prepare for the eventual gup folio conversions since this function
now supports individual subpages from large folios.
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
---
mm/memory.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c
index 0f9b32a20e5b..747866060658 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -6820,9 +6820,10 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
}
while (len) {
- int bytes, offset, retval;
+ int bytes, folio_offset, page_offset retval;
void *maddr;
struct page *page;
+ struct folio *folio;
struct vm_area_struct *vma = NULL;
page = get_user_page_vma_remote(mm, addr, gup_flags, &vma);
@@ -6837,17 +6838,20 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
goto out;
}
+ folio = page_folio(page);
bytes = len;
- offset = addr & (PAGE_SIZE - 1);
- if (bytes > PAGE_SIZE - offset)
- bytes = PAGE_SIZE - offset;
+ folio_offset = offset_in_folio(folio, addr);
+ page_offset = offset_in_page(folio_offset);
+
+ if (bytes > PAGE_SIZE - page_offset)
+ bytes = PAGE_SIZE - page_offset;
- maddr = kmap_local_page(page);
- retval = strscpy(buf, maddr + offset, bytes);
+ maddr = kmap_local_folio(folio, folio_offset);
+ retval = strscpy(buf, maddr, bytes);
if (retval >= 0) {
/* Found the end of the string */
buf += retval;
- unmap_and_put_page(page, maddr);
+ folio_release_kmap(folio, maddr);
break;
}
@@ -6859,13 +6863,16 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
*/
if (bytes != len) {
addr += bytes - 1;
- copy_from_user_page(vma, page, addr, buf, maddr + (PAGE_SIZE - 1), 1);
+ copy_from_user_page(vma,
+ folio_page(folio, folio_offset / PAGE_SIZE),
+ addr, buf,
+ maddr + (PAGE_SIZE - page_offset - 1), 1);
buf += 1;
addr += 1;
}
len -= bytes;
- unmap_and_put_page(page, maddr);
+ folio_release_kmap(folio, maddr);
}
out:
--
2.49.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC PATCH 2/3] mm/memory.c: convert __access_remote_vm() to folios
2025-06-25 17:48 [RFC PATCH 0/3] Some remote_vm folio conversions Vishal Moola (Oracle)
2025-06-25 17:48 ` [RFC PATCH 1/3] mm/memory.c: convert __copy_remote_vm_str() to folios Vishal Moola (Oracle)
@ 2025-06-25 17:48 ` Vishal Moola (Oracle)
2025-06-25 17:48 ` [RFC PATCH 3/3] mm: Remove unmap_and_put_page() Vishal Moola (Oracle)
2 siblings, 0 replies; 9+ messages in thread
From: Vishal Moola (Oracle) @ 2025-06-25 17:48 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Matthew Wilcox (Oracle), David Hildenbrand,
Jordan Rome, Andrew Morton, Vishal Moola (Oracle)
Use kmap_local_folio() instead of kmap_local_page().
Replaces 2 calls to compound_head() with one.
This prepares us for the removal of unmap_and_put_page(), and helps
prepare for the eventual gup folio conversions since this function
now supports individual subpages from large folios.
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
---
mm/memory.c | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c
index 747866060658..5eeca95b9c61 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -6696,8 +6696,9 @@ static int __access_remote_vm(struct mm_struct *mm, unsigned long addr,
/* ignore errors, just check how much was successfully transferred */
while (len) {
- int bytes, offset;
+ int bytes, folio_offset;
void *maddr;
+ struct folio *folio;
struct vm_area_struct *vma = NULL;
struct page *page = get_user_page_vma_remote(mm, addr,
gup_flags, &vma);
@@ -6729,21 +6730,25 @@ static int __access_remote_vm(struct mm_struct *mm, unsigned long addr,
if (bytes <= 0)
break;
} else {
+ folio = page_folio(page);
bytes = len;
- offset = addr & (PAGE_SIZE-1);
- if (bytes > PAGE_SIZE-offset)
- bytes = PAGE_SIZE-offset;
+ folio_offset = offset_in_folio(folio, addr);
+
+ if (bytes > PAGE_SIZE - offset_in_page(folio_offset))
+ bytes = PAGE_SIZE - offset_in_page(folio_offset);
- maddr = kmap_local_page(page);
+ maddr = kmap_local_folio(folio, folio_offset);
if (write) {
- copy_to_user_page(vma, page, addr,
- maddr + offset, buf, bytes);
- set_page_dirty_lock(page);
+ copy_to_user_page(vma,
+ folio_page(folio, folio_offset / PAGE_SIZE),
+ addr, maddr, buf, bytes);
+ folio_mark_dirty_lock(folio);
} else {
- copy_from_user_page(vma, page, addr,
- buf, maddr + offset, bytes);
+ copy_from_user_page(vma,
+ folio_page(folio, folio_offset / PAGE_SIZE),
+ addr, buf, maddr, bytes);
}
- unmap_and_put_page(page, maddr);
+ folio_release_kmap(folio, maddr);
}
len -= bytes;
buf += bytes;
--
2.49.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC PATCH 3/3] mm: Remove unmap_and_put_page()
2025-06-25 17:48 [RFC PATCH 0/3] Some remote_vm folio conversions Vishal Moola (Oracle)
2025-06-25 17:48 ` [RFC PATCH 1/3] mm/memory.c: convert __copy_remote_vm_str() to folios Vishal Moola (Oracle)
2025-06-25 17:48 ` [RFC PATCH 2/3] mm/memory.c: convert __access_remote_vm() " Vishal Moola (Oracle)
@ 2025-06-25 17:48 ` Vishal Moola (Oracle)
2 siblings, 0 replies; 9+ messages in thread
From: Vishal Moola (Oracle) @ 2025-06-25 17:48 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Matthew Wilcox (Oracle), David Hildenbrand,
Jordan Rome, Andrew Morton, Vishal Moola (Oracle)
There are no callers of unmap_and_put_page() left. Remove it.
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
---
include/linux/highmem.h | 6 ------
1 file changed, 6 deletions(-)
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index a30526cc53a7..6234f316468c 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -682,10 +682,4 @@ static inline void folio_release_kmap(struct folio *folio, void *addr)
kunmap_local(addr);
folio_put(folio);
}
-
-static inline void unmap_and_put_page(struct page *page, void *addr)
-{
- folio_release_kmap(page_folio(page), addr);
-}
-
#endif /* _LINUX_HIGHMEM_H */
--
2.49.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/3] mm/memory.c: convert __copy_remote_vm_str() to folios
2025-06-25 17:48 ` [RFC PATCH 1/3] mm/memory.c: convert __copy_remote_vm_str() to folios Vishal Moola (Oracle)
@ 2025-06-25 18:00 ` Matthew Wilcox
2025-06-25 18:24 ` David Hildenbrand
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Matthew Wilcox @ 2025-06-25 18:00 UTC (permalink / raw)
To: Vishal Moola (Oracle)
Cc: linux-mm, linux-kernel, David Hildenbrand, Jordan Rome,
Andrew Morton
On Wed, Jun 25, 2025 at 10:48:39AM -0700, Vishal Moola (Oracle) wrote:
> +++ b/mm/memory.c
> @@ -6820,9 +6820,10 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
> }
>
> while (len) {
> - int bytes, offset, retval;
> + int bytes, folio_offset, page_offset retval;
offset_in_folio() returns a size_t so that we can support folios larger
than 2GB (which is a real possibility here; hugetlbfs might end up with
a 16GB folio on some architectures).
> @@ -6837,17 +6838,20 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
> goto out;
> }
>
> + folio = page_folio(page);
> bytes = len;
> - offset = addr & (PAGE_SIZE - 1);
> - if (bytes > PAGE_SIZE - offset)
> - bytes = PAGE_SIZE - offset;
> + folio_offset = offset_in_folio(folio, addr);
Umm. Not sure this is safe. A folio might be mapped misaligned, so
'addr' might not give you the right offset within the folio. I think
you might need to use addr - (vma->vm_pgoff << PAGE_SHIFT). But I'd
defer to others here ... particularly when it comes to anonymous folios.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/3] mm/memory.c: convert __copy_remote_vm_str() to folios
2025-06-25 18:00 ` Matthew Wilcox
@ 2025-06-25 18:24 ` David Hildenbrand
2025-06-25 19:23 ` Vishal Moola (Oracle)
2025-06-26 3:02 ` Matthew Wilcox
2 siblings, 0 replies; 9+ messages in thread
From: David Hildenbrand @ 2025-06-25 18:24 UTC (permalink / raw)
To: Matthew Wilcox, Vishal Moola (Oracle)
Cc: linux-mm, linux-kernel, Jordan Rome, Andrew Morton
On 25.06.25 20:00, Matthew Wilcox wrote:
> On Wed, Jun 25, 2025 at 10:48:39AM -0700, Vishal Moola (Oracle) wrote:
>> +++ b/mm/memory.c
>> @@ -6820,9 +6820,10 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
>> }
>>
>> while (len) {
>> - int bytes, offset, retval;
>> + int bytes, folio_offset, page_offset retval;
>
> offset_in_folio() returns a size_t so that we can support folios larger
> than 2GB (which is a real possibility here; hugetlbfs might end up with
> a 16GB folio on some architectures).
>
>> @@ -6837,17 +6838,20 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
>> goto out;
>> }
>>
>> + folio = page_folio(page);
>> bytes = len;
>> - offset = addr & (PAGE_SIZE - 1);
>> - if (bytes > PAGE_SIZE - offset)
>> - bytes = PAGE_SIZE - offset;
>> + folio_offset = offset_in_folio(folio, addr);
>
> Umm. Not sure this is safe. A folio might be mapped misaligned, so
> 'addr' might not give you the right offset within the folio. I think
> you might need to use addr - (vma->vm_pgoff << PAGE_SHIFT). But I'd
> defer to others here ... particularly when it comes to anonymous folios.
Not special to anon memory I think ... :)
Only the offset within a page is okay to derive (existing code).
--
Cheers,
David / dhildenb
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/3] mm/memory.c: convert __copy_remote_vm_str() to folios
2025-06-25 18:00 ` Matthew Wilcox
2025-06-25 18:24 ` David Hildenbrand
@ 2025-06-25 19:23 ` Vishal Moola (Oracle)
2025-06-26 3:02 ` Matthew Wilcox
2 siblings, 0 replies; 9+ messages in thread
From: Vishal Moola (Oracle) @ 2025-06-25 19:23 UTC (permalink / raw)
To: Matthew Wilcox
Cc: linux-mm, linux-kernel, David Hildenbrand, Jordan Rome,
Andrew Morton
On Wed, Jun 25, 2025 at 07:00:22PM +0100, Matthew Wilcox wrote:
> On Wed, Jun 25, 2025 at 10:48:39AM -0700, Vishal Moola (Oracle) wrote:
> > +++ b/mm/memory.c
> > @@ -6820,9 +6820,10 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
> > }
> >
> > while (len) {
> > - int bytes, offset, retval;
> > + int bytes, folio_offset, page_offset retval;
>
> offset_in_folio() returns a size_t so that we can support folios larger
> than 2GB (which is a real possibility here; hugetlbfs might end up with
> a 16GB folio on some architectures).
Got it, I'll change that.
> > @@ -6837,17 +6838,20 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
> > goto out;
> > }
> >
> > + folio = page_folio(page);
> > bytes = len;
> > - offset = addr & (PAGE_SIZE - 1);
> > - if (bytes > PAGE_SIZE - offset)
> > - bytes = PAGE_SIZE - offset;
> > + folio_offset = offset_in_folio(folio, addr);
>
> Umm. Not sure this is safe. A folio might be mapped misaligned, so
> 'addr' might not give you the right offset within the folio. I think
> you might need to use addr - (vma->vm_pgoff << PAGE_SHIFT). But I'd
> defer to others here ... particularly when it comes to anonymous folios.
Ah ok, I didn't realize folios could be misaligned. I'll play around
with your proposed calculation.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/3] mm/memory.c: convert __copy_remote_vm_str() to folios
2025-06-25 18:00 ` Matthew Wilcox
2025-06-25 18:24 ` David Hildenbrand
2025-06-25 19:23 ` Vishal Moola (Oracle)
@ 2025-06-26 3:02 ` Matthew Wilcox
2025-06-26 8:14 ` David Hildenbrand
2 siblings, 1 reply; 9+ messages in thread
From: Matthew Wilcox @ 2025-06-26 3:02 UTC (permalink / raw)
To: Vishal Moola (Oracle)
Cc: linux-mm, linux-kernel, David Hildenbrand, Jordan Rome,
Andrew Morton
On Wed, Jun 25, 2025 at 07:00:22PM +0100, Matthew Wilcox wrote:
> > + folio_offset = offset_in_folio(folio, addr);
>
> Umm. Not sure this is safe. A folio might be mapped misaligned, so
> 'addr' might not give you the right offset within the folio. I think
> you might need to use addr - (vma->vm_pgoff << PAGE_SHIFT). But I'd
> defer to others here ... particularly when it comes to anonymous folios.
Sorry, this calculation is obviously wrong. It should be something like
the calculation in linear_page_index(), only without throwing away the
bottom PAGE_SHIFT bits. But that's for file VMAs only, and I'm not sure
what should be done for anon vmas. Possibly there is no way?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/3] mm/memory.c: convert __copy_remote_vm_str() to folios
2025-06-26 3:02 ` Matthew Wilcox
@ 2025-06-26 8:14 ` David Hildenbrand
0 siblings, 0 replies; 9+ messages in thread
From: David Hildenbrand @ 2025-06-26 8:14 UTC (permalink / raw)
To: Matthew Wilcox, Vishal Moola (Oracle)
Cc: linux-mm, linux-kernel, Jordan Rome, Andrew Morton
On 26.06.25 05:02, Matthew Wilcox wrote:
> On Wed, Jun 25, 2025 at 07:00:22PM +0100, Matthew Wilcox wrote:
>>> + folio_offset = offset_in_folio(folio, addr);
>>
>> Umm. Not sure this is safe. A folio might be mapped misaligned, so
>> 'addr' might not give you the right offset within the folio. I think
>> you might need to use addr - (vma->vm_pgoff << PAGE_SHIFT). But I'd
>> defer to others here ... particularly when it comes to anonymous folios.
>
> Sorry, this calculation is obviously wrong. It should be something like
> the calculation in linear_page_index(), only without throwing away the
> bottom PAGE_SHIFT bits. But that's for file VMAs only, and I'm not sure
> what should be done for anon vmas. Possibly there is no way?
In __folio_set_anon(), we set
folio->index = linear_page_index(vma, address);
and in __page_check_anon_rmap, we check
VM_BUG_ON_PAGE(page_pgoff(folio, page) != linear_page_index(vma, address),
So given the VMA, addr, folio, we should be able to figure out the offset
into the folio.
... but I didn't have my second coffee yet.
--
Cheers,
David / dhildenb
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-06-26 8:14 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-25 17:48 [RFC PATCH 0/3] Some remote_vm folio conversions Vishal Moola (Oracle)
2025-06-25 17:48 ` [RFC PATCH 1/3] mm/memory.c: convert __copy_remote_vm_str() to folios Vishal Moola (Oracle)
2025-06-25 18:00 ` Matthew Wilcox
2025-06-25 18:24 ` David Hildenbrand
2025-06-25 19:23 ` Vishal Moola (Oracle)
2025-06-26 3:02 ` Matthew Wilcox
2025-06-26 8:14 ` David Hildenbrand
2025-06-25 17:48 ` [RFC PATCH 2/3] mm/memory.c: convert __access_remote_vm() " Vishal Moola (Oracle)
2025-06-25 17:48 ` [RFC PATCH 3/3] mm: Remove unmap_and_put_page() Vishal Moola (Oracle)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).