On Thu, Jul 23, 2015 at 5:02 AM, Stanimir Varbanov
<stanimir.varba...@linaro.org> wrote:
> Hi Rob,
>
> I run into issues with msm drm driver while implementing a test
> application which use v4l2 vidc (venus) decoder driver to decode videos
> and msm drm driver to display the decoded frames. The v4l2 test
> application use msm drm as dmabuf exporter by DRM_IOCTL_MODE_CREATE_DUMB
> and DRM_IOCTL_PRIME_HANDLE_TO_FD from libdrm.
>
> So far the test app is able to decode and display using dmabuf type of
> buffers (so, to honest it is slower than using mmap & memcpy but this is
> another story). The problems start when destroying drm buffers by call
> to DRM_IOCTL_MODE_DESTROY_DUMB ioctl and also when closing dmabuf fd.
> The issues I'm seeing are:
>
> - the first and the major one happens in msm_gem_free_object() where we
> are trying to free sg table which table is already freed by drm_prime
> core in dmabuf .detach callback. In fact the msm_gem_free_object is
> called by dmabuf .release callback which should be happened after
> .detach. I find weird to call sg_table_free in .detach callback and did
> not understand why it is there.

so, I think in msm_gem_prime_get_sg_table() we need to create a
duplicate sgt.. since dma_buf_map_attachment() (and therefore
->gem_prime_get_sg_table()) returns ownership of the sgt.  So it is
not correct to be returning our own internal copy.

> - the second one is again in msm_gem.c::put_pages dma_unmap_sg call.
> Some background, vidc (venus) driver use dma-iommu infrastructure copped
> from qcom downstream kernel to abstract iommu map/unmap [1].
> On the other side when drm driver is exporter it use swiotbl [2] dma map
> operations, dma_map_sg will fill sg->dma_address with phy addresses. So
> when vidc call dma_map_sg the sg dma_address is filled with iova address
> then drm call dma_unmap_sg expecting phy addresses.

hmm.. so drm_gem_map_dma_buf() should dma_map_sg() using attach->dev
(which should be vidc, not drm).  Maybe something unexepected was
happening there since we were incorrectly returning our own sgt (which
had already been dma_map_sg()'d w/ the drm device for cache
maintenance?

Could you try:

-------------
diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c
b/drivers/gpu/drm/msm/msm_gem_prime.c
index dd7a7ab..831461b 100644
--- a/drivers/gpu/drm/msm/msm_gem_prime.c
+++ b/drivers/gpu/drm/msm/msm_gem_prime.c
@@ -23,8 +23,12 @@
 struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj)
 {
     struct msm_gem_object *msm_obj = to_msm_bo(obj);
-    BUG_ON(!msm_obj->sgt);  /* should have already pinned! */
-    return msm_obj->sgt;
+    int npages = obj->size >> PAGE_SHIFT;
+
+    if (WARN_ON(!msm_obj->pages))  /* should have already pinned! */
+        return NULL;
+
+    return drm_prime_pages_to_sg(msm_obj->pages, npages);
 }

 void *msm_gem_prime_vmap(struct drm_gem_object *obj)
-------------

> If I didn't express myself well, see the hack bellow which I made to
> prevent kernel crash.
>
> Any thoughts?
>
> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
> index 7482b06cd08f..c4c0f8084b11 100644
> --- a/drivers/gpu/drm/drm_prime.c
> +++ b/drivers/gpu/drm/drm_prime.c
> @@ -155,10 +155,10 @@ static void drm_gem_map_detach(struct dma_buf
> *dma_buf,
>                 if (prime_attach->dir != DMA_NONE)
>                         dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents,
>                                         prime_attach->dir);
> -               sg_free_table(sgt);
> +/*             sg_free_table(sgt);*/
>         }
>
> -       kfree(sgt);
> +/*     kfree(sgt);*/
>         kfree(prime_attach);
>         attach->priv = NULL;
>  }
> diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
> index 9b6220140e99..a78a24ca2fda 100644
> --- a/drivers/gpu/drm/msm/msm_gem.c
> +++ b/drivers/gpu/drm/msm/msm_gem.c
> @@ -116,9 +116,10 @@ static void put_pages(struct drm_gem_object *obj)
>                 /* For non-cached buffers, ensure the new pages are clean
>                  * because display controller, GPU, etc. are not coherent:
>                  */
> -               if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
> +/*             if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
>                         dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
>                                         msm_obj->sgt->nents,
> DMA_BIDIRECTIONAL);
> +*/
>                 sg_free_table(msm_obj->sgt);
>                 kfree(msm_obj->sgt);
>
>
> --
> regards,
> Stan
>
> [1]
> https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/blob/refs/heads/release/qcomlt-4.0:/arch/arm64/mm/dma-mapping.c#l1315
>
> [2]
> https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/blob/refs/heads/release/qcomlt-4.0:/arch/arm64/mm/dma-mapping.c#l350
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to