<div>This looks perfect to me and will close really the last remaining blocking issue for converting ion to be a dma-buf exporter.  Assuming there are no major objections to this I&#39;ll post some patches to the list next week that make that change to ion.  Looking forward to meeting in the middle on this!  Thanks Rob!</div>
<div><br></div><div>I&#39;m happy with the bracketing calls as well.  We&#39;ve been discussing a similar api to ion to manage the caches.  It&#39;ll allow us to enable debug features like remapping the buffers read only when a process says it&#39;s finished with them to catch cache offenders.  </div>
<div><br></div><div>Rebecca</div><br><div class="gmail_quote">On Thu, Mar 15, 2012 at 5:27 AM, Rob Clark <span dir="ltr">&lt;<a href="mailto:rob.clark@linaro.org">rob.clark@linaro.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Thu, Mar 15, 2012 at 2:16 AM, Abhinav Kochhar<br>
&lt;<a href="mailto:kochhar.abhinav@gmail.com">kochhar.abhinav@gmail.com</a>&gt; wrote:<br>
&gt; do we need to pass the dmabuf object to dmabuf-&gt;ops-&gt;mmap(dmabuf, file,<br>
&gt; vma)?<br>
&gt;<br>
&gt; as file-&gt;private_data can retrieve the dmabuf object.<br>
&gt;<br>
&gt; &quot;dmabuf = file-&gt;private_data&quot;<br>
&gt;<br>
&gt; removing dmabuf from the function arguments will keep it consistent with<br>
&gt; basic &quot;mmap&quot; definitions:<br>
&gt;<br>
&gt; &quot;static int xxxx_mmap(struct file *file, struct vm_area_struct *vma)&quot;<br>
&gt;<br>
<br>
</div>This was intentional to deviate from standard mmap fxn signature..  it<br>
was to avoid encouraging incorrect use.<br>
<br>
What I mean is, most subsystems interested in participating in dmabuf<br>
support mmap&#39;ing multiple buffers on a single chrdev, with some<br>
offset-&gt;object mapping mechanism.  But in the case of a dmabuf fd, the<br>
buffer userspace would mmap would be at offset=0.  So you wouldn&#39;t get<br>
the expected results if you just directly plugged v4l2_mmap or<br>
drm_gem_mmap, etc, into your dmabuf-ops.  Not to mention the<br>
file-&gt;file_private wouldn&#39;t be what you expected.  So basically I was<br>
just trying to follow principle-of-least-surprise ;-)<br>
<br>
BR,<br>
-R<br>
<div class="HOEnZb"><div class="h5"><br>
&gt; On Thu, Mar 15, 2012 at 10:32 AM, Rob Clark &lt;<a href="mailto:rob.clark@linaro.org">rob.clark@linaro.org</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; From: Rob Clark &lt;<a href="mailto:rob@ti.com">rob@ti.com</a>&gt;<br>
&gt;&gt;<br>
&gt;&gt; Enable optional userspace access to dma-buf buffers via mmap() on the<br>
&gt;&gt; dma-buf file descriptor.  Userspace access to the buffer should be<br>
&gt;&gt; bracketed with DMA_BUF_IOCTL_{PREPARE,FINISH}_ACCESS ioctl calls to<br>
&gt;&gt; give the exporting driver a chance to deal with cache synchronization<br>
&gt;&gt; and such for cached userspace mappings without resorting to page<br>
&gt;&gt; faulting tricks.  The reasoning behind this is that, while drm<br>
&gt;&gt; drivers tend to have all the mechanisms in place for dealing with<br>
&gt;&gt; page faulting tricks, other driver subsystems may not.  And in<br>
&gt;&gt; addition, while page faulting tricks make userspace simpler, there<br>
&gt;&gt; are some associated overheads.<br>
&gt;&gt;<br>
&gt;&gt; In all cases, the mmap() call is allowed to fail, and the associated<br>
&gt;&gt; dma_buf_ops are optional (mmap() will fail if at least the mmap()<br>
&gt;&gt; op is not implemented by the exporter, but in either case the<br>
&gt;&gt; {prepare,finish}_access() ops are optional).<br>
&gt;&gt;<br>
&gt;&gt; For now the prepare/finish access ioctls are kept simple with no<br>
&gt;&gt; argument, although there is possibility to add additional ioctls<br>
&gt;&gt; (or simply change the existing ioctls from _IO() to _IOW()) later<br>
&gt;&gt; to provide optimization to allow userspace to specify a region of<br>
&gt;&gt; interest.<br>
&gt;&gt;<br>
&gt;&gt; For a final patch, dma-buf.h would need to be split into what is<br>
&gt;&gt; exported to userspace, and what is kernel private, but I wanted to<br>
&gt;&gt; get feedback on the idea of requiring userspace to bracket access<br>
&gt;&gt; first (vs. limiting this to coherent mappings or exporters who play<br>
&gt;&gt; page faltings plus PTE shoot-down games) before I split the header<br>
&gt;&gt; which would cause conflicts with other pending dma-buf patches.  So<br>
&gt;&gt; flame-on!<br>
&gt;&gt; ---<br>
&gt;&gt;  drivers/base/dma-buf.c  |   42 ++++++++++++++++++++++++++++++++++++++++++<br>
&gt;&gt;  include/linux/dma-buf.h |   22 ++++++++++++++++++++++<br>
&gt;&gt;  2 files changed, 64 insertions(+), 0 deletions(-)<br>
&gt;&gt;<br>
&gt;&gt; diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c<br>
&gt;&gt; index c9a945f..382b78a 100644<br>
&gt;&gt; --- a/drivers/base/dma-buf.c<br>
&gt;&gt; +++ b/drivers/base/dma-buf.c<br>
&gt;&gt; @@ -30,6 +30,46 @@<br>
&gt;&gt;<br>
&gt;&gt;  static inline int is_dma_buf_file(struct file *);<br>
&gt;&gt;<br>
&gt;&gt; +static int dma_buf_mmap(struct file *file, struct vm_area_struct *vma)<br>
&gt;&gt; +{<br>
&gt;&gt; +       struct dma_buf *dmabuf;<br>
&gt;&gt; +<br>
&gt;&gt; +       if (!is_dma_buf_file(file))<br>
&gt;&gt; +               return -EINVAL;<br>
&gt;&gt; +<br>
&gt;&gt; +       dmabuf = file-&gt;private_data;<br>
&gt;&gt; +<br>
&gt;&gt; +       if (dmabuf-&gt;ops-&gt;mmap)<br>
&gt;&gt; +               return dmabuf-&gt;ops-&gt;mmap(dmabuf, file, vma);<br>
&gt;&gt; +<br>
&gt;&gt; +       return -ENODEV;<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +static long dma_buf_ioctl(struct file *file, unsigned int cmd,<br>
&gt;&gt; +               unsigned long arg)<br>
&gt;&gt; +{<br>
&gt;&gt; +       struct dma_buf *dmabuf;<br>
&gt;&gt; +<br>
&gt;&gt; +       if (!is_dma_buf_file(file))<br>
&gt;&gt; +               return -EINVAL;<br>
&gt;&gt; +<br>
&gt;&gt; +       dmabuf = file-&gt;private_data;<br>
&gt;&gt; +<br>
&gt;&gt; +       switch (_IOC_NR(cmd)) {<br>
&gt;&gt; +       case _IOC_NR(DMA_BUF_IOCTL_PREPARE_ACCESS):<br>
&gt;&gt; +               if (dmabuf-&gt;ops-&gt;prepare_access)<br>
&gt;&gt; +                       return dmabuf-&gt;ops-&gt;prepare_access(dmabuf);<br>
&gt;&gt; +               return 0;<br>
&gt;&gt; +       case _IOC_NR(DMA_BUF_IOCTL_FINISH_ACCESS):<br>
&gt;&gt; +               if (dmabuf-&gt;ops-&gt;finish_access)<br>
&gt;&gt; +                       return dmabuf-&gt;ops-&gt;finish_access(dmabuf);<br>
&gt;&gt; +               return 0;<br>
&gt;&gt; +       default:<br>
&gt;&gt; +               return -EINVAL;<br>
&gt;&gt; +       }<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +<br>
&gt;&gt;  static int dma_buf_release(struct inode *inode, struct file *file)<br>
&gt;&gt;  {<br>
&gt;&gt;        struct dma_buf *dmabuf;<br>
&gt;&gt; @@ -45,6 +85,8 @@ static int dma_buf_release(struct inode *inode, struct<br>
&gt;&gt; file *file)<br>
&gt;&gt;  }<br>
&gt;&gt;<br>
&gt;&gt;  static const struct file_operations dma_buf_fops = {<br>
&gt;&gt; +       .mmap           = dma_buf_mmap,<br>
&gt;&gt; +       .unlocked_ioctl = dma_buf_ioctl,<br>
&gt;&gt;        .release        = dma_buf_release,<br>
&gt;&gt;  };<br>
&gt;&gt;<br>
&gt;&gt; diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h<br>
&gt;&gt; index a885b26..cbdff81 100644<br>
&gt;&gt; --- a/include/linux/dma-buf.h<br>
&gt;&gt; +++ b/include/linux/dma-buf.h<br>
&gt;&gt; @@ -34,6 +34,17 @@<br>
&gt;&gt;  struct dma_buf;<br>
&gt;&gt;  struct dma_buf_attachment;<br>
&gt;&gt;<br>
&gt;&gt; +/* TODO: dma-buf.h should be the userspace visible header, and<br>
&gt;&gt; dma-buf-priv.h (?)<br>
&gt;&gt; + * the kernel internal header.. for now just stuff these here to avoid<br>
&gt;&gt; conflicting<br>
&gt;&gt; + * with other patches..<br>
&gt;&gt; + *<br>
&gt;&gt; + * For now, no arg to keep things simple, but we could consider adding an<br>
&gt;&gt; + * optional region of interest later.<br>
&gt;&gt; + */<br>
&gt;&gt; +#define DMA_BUF_IOCTL_PREPARE_ACCESS   _IO(&#39;Z&#39;, 0)<br>
&gt;&gt; +#define DMA_BUF_IOCTL_FINISH_ACCESS    _IO(&#39;Z&#39;, 1)<br>
&gt;&gt; +<br>
&gt;&gt; +<br>
&gt;&gt;  /**<br>
&gt;&gt;  * struct dma_buf_ops - operations possible on struct dma_buf<br>
&gt;&gt;  * @attach: [optional] allows different devices to &#39;attach&#39; themselves to<br>
&gt;&gt; the<br>
&gt;&gt; @@ -49,6 +60,13 @@ struct dma_buf_attachment;<br>
&gt;&gt;  * @unmap_dma_buf: decreases usecount of buffer, might deallocate scatter<br>
&gt;&gt;  *                pages.<br>
&gt;&gt;  * @release: release this buffer; to be called after the last dma_buf_put.<br>
&gt;&gt; + * @mmap: [optional, allowed to fail] operation called if userspace calls<br>
&gt;&gt; + *              mmap() on the dmabuf fd.  Note that userspace should use<br>
&gt;&gt; the<br>
&gt;&gt; + *              DMA_BUF_PREPARE_ACCESS / DMA_BUF_FINISH_ACCESS ioctls<br>
&gt;&gt; before/after<br>
&gt;&gt; + *              sw access to the buffer, to give the exporter an<br>
&gt;&gt; opportunity to<br>
&gt;&gt; + *              deal with cache maintenance.<br>
&gt;&gt; + * @prepare_access: [optional] handler for PREPARE_ACCESS ioctl.<br>
&gt;&gt; + * @finish_access: [optional] handler for FINISH_ACCESS ioctl.<br>
&gt;&gt;  */<br>
&gt;&gt;  struct dma_buf_ops {<br>
&gt;&gt;        int (*attach)(struct dma_buf *, struct device *,<br>
&gt;&gt; @@ -72,6 +90,10 @@ struct dma_buf_ops {<br>
&gt;&gt;        /* after final dma_buf_put() */<br>
&gt;&gt;        void (*release)(struct dma_buf *);<br>
&gt;&gt;<br>
&gt;&gt; +       int (*mmap)(struct dma_buf *, struct file *, struct vm_area_struct<br>
&gt;&gt; *);<br>
&gt;&gt; +       int (*prepare_access)(struct dma_buf *);<br>
&gt;&gt; +       int (*finish_access)(struct dma_buf *);<br>
&gt;&gt; +<br>
&gt;&gt;  };<br>
&gt;&gt;<br>
&gt;&gt;  /**<br>
&gt;&gt; --<br>
&gt;&gt; 1.7.5.4<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; _______________________________________________<br>
&gt;&gt; Linaro-mm-sig mailing list<br>
&gt;&gt; <a href="mailto:Linaro-mm-sig@lists.linaro.org">Linaro-mm-sig@lists.linaro.org</a><br>
&gt;&gt; <a href="http://lists.linaro.org/mailman/listinfo/linaro-mm-sig" target="_blank">http://lists.linaro.org/mailman/listinfo/linaro-mm-sig</a><br>
&gt;<br>
&gt;<br>
</div></div></blockquote></div><br>