[PATCH v6 03/17] misc/habana: Stop using frame_vector helpers

Oded Gabbay oded.gabbay at gmail.com
Sat Nov 21 07:47:05 EST 2020


On Thu, Nov 19, 2020 at 4:41 PM Daniel Vetter <daniel.vetter at ffwll.ch> 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.
>
> Note that pin_user_pages_fast is a safe replacement despite the
> seeming lack of checking for vma->vm_flasg & (VM_IO | VM_PFNMAP). Such
> ptes are marked with pte_mkspecial (which pup_fast rejects in the
> fastpath), and only architectures supporting that support the
> pin_user_pages_fast fastpath.
>
> Reviewed-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
> Cc: Christoph Hellwig <hch at infradead.org>
> Cc: Jason Gunthorpe <jgg at ziepe.ca>
> Cc: Andrew Morton <akpm at linux-foundation.org>
> Cc: John Hubbard <jhubbard at nvidia.com>
> Cc: Jérôme Glisse <jglisse at redhat.com>
> Cc: Jan Kara <jack at suse.cz>
> Cc: Dan Williams <dan.j.williams at intel.com>
> Cc: linux-mm at kvack.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-samsung-soc at vger.kernel.org
> Cc: linux-media at vger.kernel.org
> Cc: Oded Gabbay <oded.gabbay at gmail.com>
> Cc: Omer Shpigelman <oshpigelman at habana.ai>
> Cc: Ofir Bitton <obitton at habana.ai>
> Cc: Tomer Tayar <ttayar at habana.ai>
> Cc: Moti Haimovski <mhaimovski at habana.ai>
> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Pawel Piskorski <ppiskorski at habana.ai>
> Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
> --
> v2: Use unpin_user_pages_dirty_lock (John)
> v3: Update kerneldoc (Oded)
> v6: Explain why pup_fast is safe, after discussions with John and
> Christoph.
> ---
>  drivers/misc/habanalabs/Kconfig             |  1 -
>  drivers/misc/habanalabs/common/habanalabs.h |  6 ++-
>  drivers/misc/habanalabs/common/memory.c     | 49 ++++++++-------------
>  3 files changed, 22 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/misc/habanalabs/Kconfig b/drivers/misc/habanalabs/Kconfig
> index 1640340d3e62..293d79811372 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 GENERIC_ALLOCATOR
>         select HWMON
>         help
> diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h
> index 80d4d7385ffe..272aa3f29200 100644
> --- a/drivers/misc/habanalabs/common/habanalabs.h
> +++ b/drivers/misc/habanalabs/common/habanalabs.h
> @@ -921,7 +921,8 @@ struct hl_ctx_mgr {
>   * struct hl_userptr - memory mapping chunk information
>   * @vm_type: type of the VM.
>   * @job_node: linked-list node for hanging the object on the Job's list.
> - * @vec: pointer to the frame vector.
> + * @pages: pointer to struct page array
> + * @npages: size of @pages array
>   * @sgt: pointer to the scatter-gather table that holds the pages.
>   * @dir: for DMA unmapping, the direction must be supplied, so save it.
>   * @debugfs_list: node in debugfs list of command submissions.
> @@ -932,7 +933,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;
>         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 84227819e4d1..0b220221873d 100644
> --- a/drivers/misc/habanalabs/common/memory.c
> +++ b/drivers/misc/habanalabs/common/memory.c
> @@ -1291,45 +1291,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;
>         }
Hi Daniel, sorry but missed this in my initial review.
The error message no longer fits the code, and actually it isn't
needed as we don't print error messages on malloc failures.
With that fixed, this patch is:
Reviewed-by: Oded Gabbay <ogabbay at kernel.org>

>
> -       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);
>         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;
>  }
>
> @@ -1415,8 +1411,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)
> @@ -1424,15 +1418,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.29.2
>



More information about the linux-arm-kernel mailing list