[Linaro-mm-sig] [PATCH] RFC: dma-buf: userspace mmap support

Abhinav Kochhar kochhar.abhinav at gmail.com
Thu Mar 15 07:16:49 UTC 2012


do we need to pass the dmabuf object to dmabuf->ops->mmap(dmabuf, file,
vma)?

as file->private_data can retrieve the dmabuf object.

*"dmabuf = file->private_data"*

*removing dmabuf from the function arguments will keep it consistent with
basic "mmap" definitions: *

*"static int xxxx_mmap(struct file *file, struct vm_area_struct *vma)"*
**
On Thu, Mar 15, 2012 at 10:32 AM, Rob Clark <rob.clark at linaro.org> wrote:

> From: Rob Clark <rob at ti.com>
>
> Enable optional userspace access to dma-buf buffers via mmap() on the
> dma-buf file descriptor.  Userspace access to the buffer should be
> bracketed with DMA_BUF_IOCTL_{PREPARE,FINISH}_ACCESS ioctl calls to
> give the exporting driver a chance to deal with cache synchronization
> and such for cached userspace mappings without resorting to page
> faulting tricks.  The reasoning behind this is that, while drm
> drivers tend to have all the mechanisms in place for dealing with
> page faulting tricks, other driver subsystems may not.  And in
> addition, while page faulting tricks make userspace simpler, there
> are some associated overheads.
>
> In all cases, the mmap() call is allowed to fail, and the associated
> dma_buf_ops are optional (mmap() will fail if at least the mmap()
> op is not implemented by the exporter, but in either case the
> {prepare,finish}_access() ops are optional).
>
> For now the prepare/finish access ioctls are kept simple with no
> argument, although there is possibility to add additional ioctls
> (or simply change the existing ioctls from _IO() to _IOW()) later
> to provide optimization to allow userspace to specify a region of
> interest.
>
> For a final patch, dma-buf.h would need to be split into what is
> exported to userspace, and what is kernel private, but I wanted to
> get feedback on the idea of requiring userspace to bracket access
> first (vs. limiting this to coherent mappings or exporters who play
> page faltings plus PTE shoot-down games) before I split the header
> which would cause conflicts with other pending dma-buf patches.  So
> flame-on!
> ---
>  drivers/base/dma-buf.c  |   42 ++++++++++++++++++++++++++++++++++++++++++
>  include/linux/dma-buf.h |   22 ++++++++++++++++++++++
>  2 files changed, 64 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
> index c9a945f..382b78a 100644
> --- a/drivers/base/dma-buf.c
> +++ b/drivers/base/dma-buf.c
> @@ -30,6 +30,46 @@
>
>  static inline int is_dma_buf_file(struct file *);
>
> +static int dma_buf_mmap(struct file *file, struct vm_area_struct *vma)
> +{
> +       struct dma_buf *dmabuf;
> +
> +       if (!is_dma_buf_file(file))
> +               return -EINVAL;
> +
> +       dmabuf = file->private_data;
> +
> +       if (dmabuf->ops->mmap)
> +               return dmabuf->ops->mmap(dmabuf, file, vma);
> +
> +       return -ENODEV;
> +}
> +
> +static long dma_buf_ioctl(struct file *file, unsigned int cmd,
> +               unsigned long arg)
> +{
> +       struct dma_buf *dmabuf;
> +
> +       if (!is_dma_buf_file(file))
> +               return -EINVAL;
> +
> +       dmabuf = file->private_data;
> +
> +       switch (_IOC_NR(cmd)) {
> +       case _IOC_NR(DMA_BUF_IOCTL_PREPARE_ACCESS):
> +               if (dmabuf->ops->prepare_access)
> +                       return dmabuf->ops->prepare_access(dmabuf);
> +               return 0;
> +       case _IOC_NR(DMA_BUF_IOCTL_FINISH_ACCESS):
> +               if (dmabuf->ops->finish_access)
> +                       return dmabuf->ops->finish_access(dmabuf);
> +               return 0;
> +       default:
> +               return -EINVAL;
> +       }
> +}
> +
> +
>  static int dma_buf_release(struct inode *inode, struct file *file)
>  {
>        struct dma_buf *dmabuf;
> @@ -45,6 +85,8 @@ static int dma_buf_release(struct inode *inode, struct
> file *file)
>  }
>
>  static const struct file_operations dma_buf_fops = {
> +       .mmap           = dma_buf_mmap,
> +       .unlocked_ioctl = dma_buf_ioctl,
>        .release        = dma_buf_release,
>  };
>
> diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> index a885b26..cbdff81 100644
> --- a/include/linux/dma-buf.h
> +++ b/include/linux/dma-buf.h
> @@ -34,6 +34,17 @@
>  struct dma_buf;
>  struct dma_buf_attachment;
>
> +/* TODO: dma-buf.h should be the userspace visible header, and
> dma-buf-priv.h (?)
> + * the kernel internal header.. for now just stuff these here to avoid
> conflicting
> + * with other patches..
> + *
> + * For now, no arg to keep things simple, but we could consider adding an
> + * optional region of interest later.
> + */
> +#define DMA_BUF_IOCTL_PREPARE_ACCESS   _IO('Z', 0)
> +#define DMA_BUF_IOCTL_FINISH_ACCESS    _IO('Z', 1)
> +
> +
>  /**
>  * struct dma_buf_ops - operations possible on struct dma_buf
>  * @attach: [optional] allows different devices to 'attach' themselves to
> the
> @@ -49,6 +60,13 @@ struct dma_buf_attachment;
>  * @unmap_dma_buf: decreases usecount of buffer, might deallocate scatter
>  *                pages.
>  * @release: release this buffer; to be called after the last dma_buf_put.
> + * @mmap: [optional, allowed to fail] operation called if userspace calls
> + *              mmap() on the dmabuf fd.  Note that userspace should use
> the
> + *              DMA_BUF_PREPARE_ACCESS / DMA_BUF_FINISH_ACCESS ioctls
> before/after
> + *              sw access to the buffer, to give the exporter an
> opportunity to
> + *              deal with cache maintenance.
> + * @prepare_access: [optional] handler for PREPARE_ACCESS ioctl.
> + * @finish_access: [optional] handler for FINISH_ACCESS ioctl.
>  */
>  struct dma_buf_ops {
>        int (*attach)(struct dma_buf *, struct device *,
> @@ -72,6 +90,10 @@ struct dma_buf_ops {
>        /* after final dma_buf_put() */
>        void (*release)(struct dma_buf *);
>
> +       int (*mmap)(struct dma_buf *, struct file *, struct vm_area_struct
> *);
> +       int (*prepare_access)(struct dma_buf *);
> +       int (*finish_access)(struct dma_buf *);
> +
>  };
>
>  /**
> --
> 1.7.5.4
>
>
> _______________________________________________
> Linaro-mm-sig mailing list
> Linaro-mm-sig at lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/linaro-mm-sig
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linaro.org/pipermail/linaro-mm-sig/attachments/20120315/757718f7/attachment-0001.html>


More information about the Linaro-mm-sig mailing list