Hi Huan, > Subject: [PATCH v3 3/5] fix vmap_udmabuf error page set Please prepend a "udmabuf:" to the subject line and improve the wording. > > Currently vmap_udmabuf set page's array by each folio. > But, ubuf->folios is only contain's the folio's head page. > > That mean we repeatedly mapped the folio head page to the vmalloc area. > > Due to udmabuf can use hugetlb, if HVO enabled, tail page may not exist, > so, we can't use page array to map, instead, use pfn array. > > Signed-off-by: Huan Yang <link@xxxxxxxx> > Suggested-by: Vivek Kasireddy <vivek.kasireddy@xxxxxxxxx> > --- > drivers/dma-buf/udmabuf.c | 22 +++++++++++++++------- > 1 file changed, 15 insertions(+), 7 deletions(-) > > diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c > index 3ec72d47bb1c..4ec54c60d76c 100644 > --- a/drivers/dma-buf/udmabuf.c > +++ b/drivers/dma-buf/udmabuf.c > @@ -67,21 +67,29 @@ static int mmap_udmabuf(struct dma_buf *buf, > struct vm_area_struct *vma) > static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) > { > struct udmabuf *ubuf = buf->priv; > - struct page **pages; > + unsigned long *pfns; I wish there was a way to easily test the vmap scenario but its great that you are able to eliminate the usage of "struct page" completely from udmabuf driver, with this patch. > void *vaddr; > pgoff_t pg; > > dma_resv_assert_held(buf->resv); > > - pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), > GFP_KERNEL); > - if (!pages) > + /** > + * HVO may free tail pages, so just use pfn to map each folio > + * into vmalloc area. > + */ > + pfns = kvmalloc_array(ubuf->pagecount, sizeof(*pfns), GFP_KERNEL); > + if (!pfns) > return -ENOMEM; > > - for (pg = 0; pg < ubuf->pagecount; pg++) > - pages[pg] = &ubuf->folios[pg]->page; > + for (pg = 0; pg < ubuf->pagecount; pg++) { > + unsigned long pfn = folio_pfn(ubuf->folios[pg]); > > - vaddr = vm_map_ram(pages, ubuf->pagecount, -1); > - kvfree(pages); > + pfn += ubuf->offsets[pg] >> PAGE_SHIFT; > + pfns[pg] = pfn; > + } > + > + vaddr = vmap_pfn(pfns, ubuf->pagecount, PAGE_KERNEL); Looks like this would require a "select VMAP_PFN" in Kconfig. Thanks, Vivek > + kvfree(pfns); > if (!vaddr) > return -EINVAL; > > -- > 2.45.2