* [PATCH] iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP
@ 2024-10-27 22:23 Hugh Dickins
2024-10-28 8:41 ` Thomas Gleixner
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Hugh Dickins @ 2024-10-27 22:23 UTC (permalink / raw)
To: Alexander Viro
Cc: Andrew Morton, Christian Brauner, Matthew Wilcox,
Christoph Hellwig, Kent Overstreet, Darrick J. Wong,
Thomas Gleixner, Peter Zijlstra, linux-fsdevel, linux-block,
linux-kernel, linux-mm
generic/077 on x86_32 CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP=y with highmem,
on huge=always tmpfs, issues a warning and then hangs (interruptibly):
WARNING: CPU: 5 PID: 3517 at mm/highmem.c:622 kunmap_local_indexed+0x62/0xc9
CPU: 5 UID: 0 PID: 3517 Comm: cp Not tainted 6.12.0-rc4 #2
...
copy_page_from_iter_atomic+0xa6/0x5ec
generic_perform_write+0xf6/0x1b4
shmem_file_write_iter+0x54/0x67
Fix copy_page_from_iter_atomic() by limiting it in that case
(include/linux/skbuff.h skb_frag_must_loop() does similar).
But going forward, perhaps CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP is too
surprising, has outlived its usefulness, and should just be removed?
Fixes: 908a1ad89466 ("iov_iter: Handle compound highmem pages in copy_page_from_iter_atomic()")
Signed-off-by: Hugh Dickins <hughd@google.com>
Cc: stable@vger.kernel.org
---
lib/iov_iter.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 1abb32c0da50..94051b83fdd8 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -461,6 +461,8 @@ size_t copy_page_from_iter_atomic(struct page *page, size_t offset,
size_t bytes, struct iov_iter *i)
{
size_t n, copied = 0;
+ bool uses_kmap = IS_ENABLED(CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP) ||
+ PageHighMem(page);
if (!page_copy_sane(page, offset, bytes))
return 0;
@@ -471,7 +473,7 @@ size_t copy_page_from_iter_atomic(struct page *page, size_t offset,
char *p;
n = bytes - copied;
- if (PageHighMem(page)) {
+ if (uses_kmap) {
page += offset / PAGE_SIZE;
offset %= PAGE_SIZE;
n = min_t(size_t, n, PAGE_SIZE - offset);
@@ -482,7 +484,7 @@ size_t copy_page_from_iter_atomic(struct page *page, size_t offset,
kunmap_atomic(p);
copied += n;
offset += n;
- } while (PageHighMem(page) && copied != bytes && n > 0);
+ } while (uses_kmap && copied != bytes && n > 0);
return copied;
}
--
2.35.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP
2024-10-27 22:23 [PATCH] iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP Hugh Dickins
@ 2024-10-28 8:41 ` Thomas Gleixner
2024-10-28 18:50 ` Linus Torvalds
2024-10-28 8:55 ` Christoph Hellwig
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Thomas Gleixner @ 2024-10-28 8:41 UTC (permalink / raw)
To: Hugh Dickins, Alexander Viro
Cc: Andrew Morton, Christian Brauner, Matthew Wilcox,
Christoph Hellwig, Kent Overstreet, Darrick J. Wong,
Peter Zijlstra, linux-fsdevel, linux-block, linux-kernel,
linux-mm, Linus Torvalds
On Sun, Oct 27 2024 at 15:23, Hugh Dickins wrote:
> generic/077 on x86_32 CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP=y with highmem,
> on huge=always tmpfs, issues a warning and then hangs (interruptibly):
>
> WARNING: CPU: 5 PID: 3517 at mm/highmem.c:622 kunmap_local_indexed+0x62/0xc9
> CPU: 5 UID: 0 PID: 3517 Comm: cp Not tainted 6.12.0-rc4 #2
> ...
> copy_page_from_iter_atomic+0xa6/0x5ec
> generic_perform_write+0xf6/0x1b4
> shmem_file_write_iter+0x54/0x67
>
> Fix copy_page_from_iter_atomic() by limiting it in that case
> (include/linux/skbuff.h skb_frag_must_loop() does similar).
>
> But going forward, perhaps CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP is too
> surprising, has outlived its usefulness, and should just be removed?
It has caught real problems and as long as we have highmem support, it
should stay IMO to provide test coverage.
Thanks,
tglx
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP
2024-10-27 22:23 [PATCH] iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP Hugh Dickins
2024-10-28 8:41 ` Thomas Gleixner
@ 2024-10-28 8:55 ` Christoph Hellwig
2024-10-28 12:41 ` Christian Brauner
2024-10-28 14:04 ` Matthew Wilcox
3 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2024-10-28 8:55 UTC (permalink / raw)
To: Hugh Dickins
Cc: Alexander Viro, Andrew Morton, Christian Brauner, Matthew Wilcox,
Christoph Hellwig, Kent Overstreet, Darrick J. Wong,
Thomas Gleixner, Peter Zijlstra, linux-fsdevel, linux-block,
linux-kernel, linux-mm
On Sun, Oct 27, 2024 at 03:23:23PM -0700, Hugh Dickins wrote:
> generic/077 on x86_32 CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP=y with highmem,
> on huge=always tmpfs, issues a warning and then hangs (interruptibly):
Looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP
2024-10-27 22:23 [PATCH] iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP Hugh Dickins
2024-10-28 8:41 ` Thomas Gleixner
2024-10-28 8:55 ` Christoph Hellwig
@ 2024-10-28 12:41 ` Christian Brauner
2024-10-28 14:04 ` Matthew Wilcox
3 siblings, 0 replies; 6+ messages in thread
From: Christian Brauner @ 2024-10-28 12:41 UTC (permalink / raw)
To: Hugh Dickins
Cc: Christian Brauner, Andrew Morton, Matthew Wilcox,
Christoph Hellwig, Kent Overstreet, Darrick J. Wong,
Thomas Gleixner, Peter Zijlstra, linux-fsdevel, linux-block,
linux-kernel, linux-mm, Alexander Viro
On Sun, 27 Oct 2024 15:23:23 -0700, Hugh Dickins wrote:
> generic/077 on x86_32 CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP=y with highmem,
> on huge=always tmpfs, issues a warning and then hangs (interruptibly):
>
> WARNING: CPU: 5 PID: 3517 at mm/highmem.c:622 kunmap_local_indexed+0x62/0xc9
> CPU: 5 UID: 0 PID: 3517 Comm: cp Not tainted 6.12.0-rc4 #2
> ...
> copy_page_from_iter_atomic+0xa6/0x5ec
> generic_perform_write+0xf6/0x1b4
> shmem_file_write_iter+0x54/0x67
>
> [...]
Applied to the vfs.fixes branch of the vfs/vfs.git tree.
Patches in the vfs.fixes branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs.fixes
[1/1] iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP
https://git.kernel.org/vfs/vfs/c/c749d9b7ebbc
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP
2024-10-27 22:23 [PATCH] iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP Hugh Dickins
` (2 preceding siblings ...)
2024-10-28 12:41 ` Christian Brauner
@ 2024-10-28 14:04 ` Matthew Wilcox
3 siblings, 0 replies; 6+ messages in thread
From: Matthew Wilcox @ 2024-10-28 14:04 UTC (permalink / raw)
To: Hugh Dickins
Cc: Alexander Viro, Andrew Morton, Christian Brauner,
Christoph Hellwig, Kent Overstreet, Darrick J. Wong,
Thomas Gleixner, Peter Zijlstra, linux-fsdevel, linux-block,
linux-kernel, linux-mm
On Sun, Oct 27, 2024 at 03:23:23PM -0700, Hugh Dickins wrote:
> generic/077 on x86_32 CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP=y with highmem,
> on huge=always tmpfs, issues a warning and then hangs (interruptibly):
> +++ b/lib/iov_iter.c
> @@ -461,6 +461,8 @@ size_t copy_page_from_iter_atomic(struct page *page, size_t offset,
> size_t bytes, struct iov_iter *i)
> {
> size_t n, copied = 0;
> + bool uses_kmap = IS_ENABLED(CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP) ||
> + PageHighMem(page);
>
> if (!page_copy_sane(page, offset, bytes))
> return 0;
> @@ -471,7 +473,7 @@ size_t copy_page_from_iter_atomic(struct page *page, size_t offset,
> char *p;
>
> n = bytes - copied;
> - if (PageHighMem(page)) {
> + if (uses_kmap) {
> page += offset / PAGE_SIZE;
> offset %= PAGE_SIZE;
> n = min_t(size_t, n, PAGE_SIZE - offset);
Urgh. I've done this same optimisation elsewhere.
memcpy_from_folio:
if (folio_test_highmem(folio) &&
chunk > PAGE_SIZE - offset_in_page(offset))
chunk = PAGE_SIZE - offset_in_page(offset);
also memcpy_to_folio(), folio_zero_tail(), folio_fill_tail(),
memcpy_from_file_folio()
I think that means we need a new predicate. I don't have a good name
yet. folio_kmap_can_access_multiple_pages() is a bit too wordy. Anyone
think of a good one?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP
2024-10-28 8:41 ` Thomas Gleixner
@ 2024-10-28 18:50 ` Linus Torvalds
0 siblings, 0 replies; 6+ messages in thread
From: Linus Torvalds @ 2024-10-28 18:50 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Hugh Dickins, Alexander Viro, Andrew Morton, Christian Brauner,
Matthew Wilcox, Christoph Hellwig, Kent Overstreet,
Darrick J. Wong, Peter Zijlstra, linux-fsdevel, linux-block,
linux-kernel, linux-mm
On Sun, 27 Oct 2024 at 22:41, Thomas Gleixner <tglx@linutronix.de> wrote:
>
> It has caught real problems and as long as we have highmem support, it
> should stay IMO to provide test coverage.
Yeah. I'd love to get rid of highmem support entirely, and that day
*will* come. Old 32-bit architectures that do stupid things can just
deal with old kernels, we need to leave that braindamage behind some
day.
But as long as we support it, we should at least also have the debug
support for it on sane hardware.
Of course, maybe we should just make PageHighMem() always return true
for CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP, but I suspect that would cause
more pain than is worth it.
But yeah, I do think we should seriously start thinking about just
getting rid of HIGHMEM.
Linus
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-10-28 18:51 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-27 22:23 [PATCH] iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP Hugh Dickins
2024-10-28 8:41 ` Thomas Gleixner
2024-10-28 18:50 ` Linus Torvalds
2024-10-28 8:55 ` Christoph Hellwig
2024-10-28 12:41 ` Christian Brauner
2024-10-28 14:04 ` Matthew Wilcox
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox