On Tue, Mar 10, 2026 at 1:53 AM Linus Walleij <linusw(a)kernel.org> wrote:
>
> Currently the CMA allocator clears highmem pages using
> kmap()->clear_page()->kunmap(), but there is a helper
> static inline in <linux/highmem.h> that does the same for
> us so use clear_highpage() instead of open coding this.
>
> Suggested-by: T.J. Mercier <tjmercier(a)google.com>
> Signed-off-by: Linus Walleij <linusw(a)kernel.org>
Reviewed-by: T.J. Mercier <tjmercier(a)google.com>
Thanks!
On Tue, 10 Mar 2026 09:53:10 +0100, Linus Walleij wrote:
> Use clear_pages() and clear_highpage() properly in the
> DMA heap allocator.
>
> Signed-off-by: Linus Walleij <linusw(a)kernel.org>
Reviewed-by: Maxime Ripard <mripard(a)kernel.org>
Thanks!
Maxime
On Tue, Mar 10, 2026 at 05:49:23AM +0000, Kasireddy, Vivek wrote:
> There are a couple of reasons why we got rid of the pages array:
> - Back then, there was some confusion about whether a struct page would
> exist or not for tail pages when HVO is enabled. Regardless, there was also
> a concern about exposing tail pages outside hugetlb code.
The existing code relies on struct page for the vmap:
for (pg = 0; pg < ubuf->pagecount; pg++)
pages[pg] = folio_page(ubuf->folios[pg],
ubuf->offsets[pg] >> PAGE_SHIFT);
Tail pages always exist, they are required by many interfaces.
> - And, we also wanted to prepare for a future where struct page would not
> exist anymore, so, it made sense to just use folios only.
If you can 100% stick with whole folios then great, but we don't have
the APIs for that cases udmabuf needs right now. Most likely we'd
expect to use phys_addr_t for scatterlist and direct full folio for
vmap. Neither is helped by the datastructure in udmabuf.
Jason
On 3/10/26 09:53, Linus Walleij wrote:
> Currently the CMA allocator clears highmem pages using
> kmap()->clear_page()->kunmap(), but there is a helper
> static inline in <linux/highmem.h> that does the same for
> us so use clear_highpage() instead of open coding this.
>
> Suggested-by: T.J. Mercier <tjmercier(a)google.com>
> Signed-off-by: Linus Walleij <linusw(a)kernel.org>
Ah yes, somebody pointed that out to me before but I never found time to write a patch to clean it up.
Reviewed-by: Christian König <christian.koenig(a)amd.com>
> ---
> drivers/dma-buf/heaps/cma_heap.c | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
> diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
> index f0bacf25ed9d..92865786cfc9 100644
> --- a/drivers/dma-buf/heaps/cma_heap.c
> +++ b/drivers/dma-buf/heaps/cma_heap.c
> @@ -329,10 +329,7 @@ static struct dma_buf *cma_heap_allocate(struct dma_heap *heap,
> struct page *page = cma_pages;
>
> while (nr_clear_pages > 0) {
> - void *vaddr = kmap_local_page(page);
> -
> - clear_page(vaddr);
> - kunmap_local(vaddr);
> + clear_highpage(page);
> /*
> * Avoid wasting time zeroing memory if the process
> * has been killed by SIGKILL.
>
> --
> 2.53.0
>
On Tue, Mar 3, 2026 at 4:25 PM Linus Walleij <linusw(a)kernel.org> wrote:
>
> As of commit 62a9f5a85b98
> "mm: introduce clear_pages() and clear_user_pages()" we can
> clear a range of pages with a potentially assembly-optimized
> call.
>
> Instead of using a memset, use this helper to clear the whole
> range of pages from the CMA allocation.
>
> Signed-off-by: Linus Walleij <linusw(a)kernel.org>
> ---
> drivers/dma-buf/heaps/cma_heap.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/dma-buf/heaps/cma_heap.c
b/drivers/dma-buf/heaps/cma_heap.c
> index bd3370b9a3f6..f0bacf25ed9d 100644
> --- a/drivers/dma-buf/heaps/cma_heap.c
> +++ b/drivers/dma-buf/heaps/cma_heap.c
> @@ -343,7 +343,7 @@ static struct dma_buf *cma_heap_allocate(struct
dma_heap *heap,
> nr_clear_pages--;
> }
> } else {
> - memset(page_address(cma_pages), 0, size);
> + clear_pages(page_address(cma_pages), pagecount);
> }
>
> buffer->pages = kmalloc_objs(*buffer->pages, pagecount);
>
> ---
> base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
> change-id: 20260303-cma-heap-clear-pages-540f3ac9f734
>
> Best regards,
> --
> Linus Walleij <linusw(a)kernel.org>
>
Hi Linus,
I think we can also use clear_highpage (singular) instead of memset in the
while loop above here to be a little more concise.
Thanks,
T.J.