media: vb2-dma-contig: add a hack to speed up cache management
authorMarek Szyprowski <m.szyprowski@samsung.com>
Tue, 22 Apr 2014 11:14:08 +0000 (13:14 +0200)
committerChanho Park <chanho61.park@samsung.com>
Tue, 18 Nov 2014 02:47:30 +0000 (11:47 +0900)
In most cases video processing is done with coherent (non-cachable) userspace mappings. In such case for USERPTR mode cache management can
be skipped. This patch introduces code for such optimisation. It is called
a hack, because it is not possible in generic way to detect if the
given userspace mapping is coherent on not.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Change-id: I86aa292455371f1b18eb3f6b765234dc04ff937b

drivers/media/v4l2-core/videobuf2-dma-contig.c

index efdaca4..4e4d175 100644 (file)
@@ -40,6 +40,7 @@ struct vb2_dc_buf {
 
        /* USERPTR related */
        struct vm_area_struct           *vma;
+       bool                            coherent;
 
        /* DMABUF related */
        struct dma_buf_attachment       *db_attach;
@@ -114,7 +115,7 @@ static void vb2_dc_prepare(void *buf_priv)
        struct sg_table *sgt = buf->dma_sgt;
 
        /* DMABUF exporter will flush the cache for us */
-       if (!sgt || buf->db_attach)
+       if (!sgt || buf->db_attach || buf->coherent)
                return;
 
        dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
@@ -126,7 +127,7 @@ static void vb2_dc_finish(void *buf_priv)
        struct sg_table *sgt = buf->dma_sgt;
 
        /* DMABUF exporter will flush the cache for us */
-       if (!sgt || buf->db_attach)
+       if (!sgt || buf->db_attach || buf->coherent)
                return;
 
        dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
@@ -423,6 +424,28 @@ static inline int vma_is_io(struct vm_area_struct *vma)
        return !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
 }
 
+#ifdef __arm__
+static inline int vma_is_coherent(struct vm_area_struct *vma)
+{
+       pgprot_t prot = vma->vm_page_prot;
+       /*
+        * this is a hack to speed up cache management on coherent arm mappings,
+        * other architectures rely on dma-mapping internal optimisations.
+        */
+       if (vma_is_io(vma) || prot == pgprot_noncached(prot) ||
+           prot == pgprot_writecombine(prot) ||
+           prot == pgprot_dmacoherent(prot))
+               return true;
+
+       return false;
+}
+#else
+static inline int vma_is_coherent(struct vm_area_struct *vma)
+{
+       return false;
+}
+#endif
+
 static int vb2_dc_get_user_pfn(unsigned long start, int n_pages,
        struct vm_area_struct *vma, unsigned long *res)
 {
@@ -614,6 +637,8 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
                goto fail_pages;
        }
 
+       buf->coherent = vma_is_coherent(vma);
+
        /* extract page list from userspace mapping */
        ret = vb2_dc_get_user_pages(start, pages, n_pages, vma, write);
        if (ret) {