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: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-15 5:30 [PATCH] mm/vmalloc: map contiguous pages in batches for vmap() whenever possible 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]
2026-04-03 9:20 ` Barry Song
2026-04-13 20:34 ` Barry Song (Xiaomi)
2025-12-18 14:00 ` Uladzislau Rezki
2025-12-18 20:05 ` Barry Song
2026-01-14 12:59 ` David Hildenbrand (Red Hat)
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 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.