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