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?