On Fri, Oct 9, 2020 at 10:59 AM Daniel Vetter <daniel.vetter@xxxxxxxx> wrote: > > All we need are a pages array, pin_user_pages_fast can give us that > directly. Plus this avoids the entire raw pfn side of get_vaddr_frames. > Thanks for the patch Daniel. > Signed-off-by: Daniel Vetter <daniel.vetter@xxxxxxxxx> > Cc: Jason Gunthorpe <jgg@xxxxxxxx> > Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> > Cc: John Hubbard <jhubbard@xxxxxxxxxx> > Cc: Jérôme Glisse <jglisse@xxxxxxxxxx> > Cc: Jan Kara <jack@xxxxxxx> > Cc: Dan Williams <dan.j.williams@xxxxxxxxx> > Cc: linux-mm@xxxxxxxxx > Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx > Cc: linux-samsung-soc@xxxxxxxxxxxxxxx > Cc: linux-media@xxxxxxxxxxxxxxx > Cc: Oded Gabbay <oded.gabbay@xxxxxxxxx> > Cc: Omer Shpigelman <oshpigelman@xxxxxxxxx> > Cc: Ofir Bitton <obitton@xxxxxxxxx> > Cc: Tomer Tayar <ttayar@xxxxxxxxx> > Cc: Moti Haimovski <mhaimovski@xxxxxxxxx> > Cc: Daniel Vetter <daniel.vetter@xxxxxxxx> > Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> > Cc: Pawel Piskorski <ppiskorski@xxxxxxxxx> > -- > v2: Use unpin_user_pages_dirty_lock (John) > --- > drivers/misc/habanalabs/Kconfig | 1 - > drivers/misc/habanalabs/common/habanalabs.h | 3 +- > drivers/misc/habanalabs/common/memory.c | 49 ++++++++------------- > 3 files changed, 20 insertions(+), 33 deletions(-) > > diff --git a/drivers/misc/habanalabs/Kconfig b/drivers/misc/habanalabs/Kconfig > index 8eb5d38c618e..2f04187f7167 100644 > --- a/drivers/misc/habanalabs/Kconfig > +++ b/drivers/misc/habanalabs/Kconfig > @@ -6,7 +6,6 @@ > config HABANA_AI > tristate "HabanaAI accelerators (habanalabs)" > depends on PCI && HAS_IOMEM > - select FRAME_VECTOR > select DMA_SHARED_BUFFER > select GENERIC_ALLOCATOR > select HWMON > diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h > index edbd627b29d2..c1b3ad613b15 100644 > --- a/drivers/misc/habanalabs/common/habanalabs.h > +++ b/drivers/misc/habanalabs/common/habanalabs.h > @@ -881,7 +881,8 @@ struct hl_ctx_mgr { > struct hl_userptr { > enum vm_type_t vm_type; /* must be first */ > struct list_head job_node; > - struct frame_vector *vec; > + struct page **pages; > + unsigned int npages; Can you please update the kerneldoc comment section of this structure according to your changes ? > struct sg_table *sgt; > enum dma_data_direction dir; > struct list_head debugfs_list; > diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c > index 5ff4688683fd..327b64479f97 100644 > --- a/drivers/misc/habanalabs/common/memory.c > +++ b/drivers/misc/habanalabs/common/memory.c > @@ -1281,45 +1281,41 @@ static int get_user_memory(struct hl_device *hdev, u64 addr, u64 size, > return -EFAULT; > } > > - userptr->vec = frame_vector_create(npages); > - if (!userptr->vec) { > + userptr->pages = kvmalloc_array(npages, sizeof(*userptr->pages), > + GFP_KERNEL); > + if (!userptr->pages) { > dev_err(hdev->dev, "Failed to create frame vector\n"); > return -ENOMEM; > } > > - rc = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE, > - userptr->vec); > + rc = pin_user_pages_fast(start, npages, FOLL_FORCE | FOLL_WRITE, > + userptr->pages); > > if (rc != npages) { > dev_err(hdev->dev, > "Failed to map host memory, user ptr probably wrong\n"); > if (rc < 0) > - goto destroy_framevec; > + goto destroy_pages; > + npages = rc; > rc = -EFAULT; > - goto put_framevec; > - } > - > - if (frame_vector_to_pages(userptr->vec) < 0) { > - dev_err(hdev->dev, > - "Failed to translate frame vector to pages\n"); > - rc = -EFAULT; > - goto put_framevec; > + goto put_pages; > } > + userptr->npages = npages; > > rc = sg_alloc_table_from_pages(userptr->sgt, > - frame_vector_pages(userptr->vec), > - npages, offset, size, GFP_ATOMIC); > + userptr->pages, > + npages, offset, size, GFP_ATOMIC); I think that because the call to kvmalloc_array() is done with GFP_KERNEL, there is no point in using GFP_ATOMIC here. And actually, this path only needs to avoid yielding when using a special debug mode. So I suggest putting here GFP_KERNEL. In the meanwhile, I'll run this patch (coupled with the next patch) in our C/I to make sure there are no regressions. Thanks, Oded > if (rc < 0) { > dev_err(hdev->dev, "failed to create SG table from pages\n"); > - goto put_framevec; > + goto put_pages; > } > > return 0; > > -put_framevec: > - put_vaddr_frames(userptr->vec); > -destroy_framevec: > - frame_vector_destroy(userptr->vec); > +put_pages: > + unpin_user_pages(userptr->pages, npages); > +destroy_pages: > + kvfree(userptr->pages); > return rc; > } > > @@ -1405,8 +1401,6 @@ int hl_pin_host_memory(struct hl_device *hdev, u64 addr, u64 size, > */ > void hl_unpin_host_memory(struct hl_device *hdev, struct hl_userptr *userptr) > { > - struct page **pages; > - > hl_debugfs_remove_userptr(hdev, userptr); > > if (userptr->dma_mapped) > @@ -1414,15 +1408,8 @@ void hl_unpin_host_memory(struct hl_device *hdev, struct hl_userptr *userptr) > userptr->sgt->nents, > userptr->dir); > > - pages = frame_vector_pages(userptr->vec); > - if (!IS_ERR(pages)) { > - int i; > - > - for (i = 0; i < frame_vector_count(userptr->vec); i++) > - set_page_dirty_lock(pages[i]); > - } > - put_vaddr_frames(userptr->vec); > - frame_vector_destroy(userptr->vec); > + unpin_user_pages_dirty_lock(userptr->pages, userptr->npages, true); > + kvfree(userptr->pages); > > list_del(&userptr->job_node); > > -- > 2.28.0 >