From: Uladzislau Rezki <urezki@gmail.com>
To: Barry Song <21cnbao@gmail.com>
Cc: urezki@gmail.com, akpm@linux-foundation.org, david@kernel.org,
dri-devel@lists.freedesktop.org, jstultz@google.com,
linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org,
linux-media@vger.kernel.org, linux-mm@kvack.org,
mripard@kernel.org, sumit.semwal@linaro.org,
v-songbaohua@oppo.com, zhengtangquan@oppo.com
Subject: Re: [PATCH] mm/vmalloc: map contiguous pages in batches for vmap() whenever possible
Date: Mon, 5 Jan 2026 17:28:52 +0100 [thread overview]
Message-ID: <aVvmxGUp2l0Tavwb@milan> (raw)
In-Reply-To: <20251223212336.36249-1-21cnbao@gmail.com>
On Wed, Dec 24, 2025 at 10:23:34AM +1300, Barry Song wrote:
> > > /*
> > > * vmap_pages_range_noflush is similar to vmap_pages_range, but does not
> > > * flush caches.
> > > @@ -658,20 +672,35 @@ int __vmap_pages_range_noflush(unsigned long addr, unsigned long end,
> > >
> > > WARN_ON(page_shift < PAGE_SHIFT);
> > >
> > > + /*
> > > + * For vmap(), users may allocate pages from high orders down to
> > > + * order 0, while always using PAGE_SHIFT as the page_shift.
> > > + * We first check whether the initial page is a compound page. If so,
> > > + * there may be an opportunity to batch multiple pages together.
> > > + */
> > > if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMALLOC) ||
> > > - page_shift == PAGE_SHIFT)
> > > + (page_shift == PAGE_SHIFT && !PageCompound(pages[0])))
> > > return vmap_small_pages_range_noflush(addr, end, prot, pages);
> > Hm.. If first few pages are order-0 and the rest are compound
> > then we do nothing.
>
> Now the dma-buf is allocated in descending order. If page0
> is not huge, page1 will not be either. However, I agree that
> we may extend support for this case.
>
> >
> > >
> > > - for (i = 0; i < nr; i += 1U << (page_shift - PAGE_SHIFT)) {
> > > + for (i = 0; i < nr; ) {
> > > + unsigned int shift = page_shift;
> > > int err;
> > >
> > > - err = vmap_range_noflush(addr, addr + (1UL << page_shift),
> > > + /*
> > > + * For vmap() cases, page_shift is always PAGE_SHIFT, even
> > > + * if the pages are physically contiguous, they may still
> > > + * be mapped in a batch.
> > > + */
> > > + if (page_shift == PAGE_SHIFT)
> > > + shift += get_vmap_batch_order(pages, nr - i, i);
> > > + err = vmap_range_noflush(addr, addr + (1UL << shift),
> > > page_to_phys(pages[i]), prot,
> > > - page_shift);
> > > + shift);
> > > if (err)
> > > return err;
> > >
> > > - addr += 1UL << page_shift;
> > > + addr += 1UL << shift;
> > > + i += 1U << shift;
> > > }
> > >
> > > return 0;
> > >
> > > Does this look clearer?
> > >
I think so, at least the place:
<snip>
[ 2.959030] Oops: Oops: 0000 [#66] SMP NOPTI
[ 2.960004] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.18.0+ #220 PREEMPT(none)
[ 2.961781] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 2.963870] BUG: unable to handle page fault for address: ffffffff3fd68118
[ 2.965383] #PF: supervisor read access in kernel mode
[ 2.966532] #PF: error_code(0x0000) - not-present page
[ 2.967682] BAD
<snip>
but it is broken for sure:
i += 1U << shift - "i" is an index in the page array.
For example if order-0 you jump 4096 indices ahead.
Should be: i += 1U << (shift - PAGE_SHIFT)
vmap_page_range() does flushing and it has instrumented KMSAN inside.
We should follow same semantic. Also it uses ioremap_max_page_shift as
maximum page shift policy.
--
Uladzislau Rezki
next prev parent reply other threads:[~2026-01-05 16:29 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-15 5:30 Barry Song
2025-12-18 13:01 ` David Hildenbrand (Red Hat)
2025-12-18 13:54 ` Uladzislau Rezki
2025-12-18 21:24 ` Barry Song
2025-12-22 13:08 ` Uladzislau Rezki
2025-12-23 21:23 ` Barry Song
2026-01-05 16:28 ` Uladzislau Rezki [this message]
2025-12-18 14:00 ` Uladzislau Rezki
2025-12-18 20:05 ` Barry Song
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aVvmxGUp2l0Tavwb@milan \
--to=urezki@gmail.com \
--cc=21cnbao@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=david@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=jstultz@google.com \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mripard@kernel.org \
--cc=sumit.semwal@linaro.org \
--cc=v-songbaohua@oppo.com \
--cc=zhengtangquan@oppo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox