From patchwork Fri Dec 7 08:31:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Inki Dae X-Patchwork-Id: 1849131 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 10DD0DF2EE for ; Fri, 7 Dec 2012 08:33:03 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E8987E5FD7 for ; Fri, 7 Dec 2012 00:33:02 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout4.samsung.com (mailout4.samsung.com [203.254.224.34]) by gabe.freedesktop.org (Postfix) with ESMTP id 52776E60FE for ; Fri, 7 Dec 2012 00:31:49 -0800 (PST) Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MEN00BHTJOVDAQ0@mailout4.samsung.com> for dri-devel@lists.freedesktop.org; Fri, 07 Dec 2012 17:31:48 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [203.254.230.42]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id B9.62.01231.379A1C05; Fri, 07 Dec 2012 17:31:47 +0900 (KST) X-AuditID: cbfee61a-b7fa66d0000004cf-ea-50c1a973188a Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 69.62.01231.379A1C05; Fri, 07 Dec 2012 17:31:47 +0900 (KST) Received: from daeinki-desktop.10.32.193.11 ([10.90.51.53]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MEN00FW2JOZ2980@mmp2.samsung.com> for dri-devel@lists.freedesktop.org; Fri, 07 Dec 2012 17:31:47 +0900 (KST) From: Inki Dae To: airlied@linux.ie, dri-devel@lists.freedesktop.org Subject: [PATCH] drm/exynos: add dmabuf attach/detach callbacks. Date: Fri, 07 Dec 2012 17:31:46 +0900 Message-id: <1354869106-3270-1-git-send-email-inki.dae@samsung.com> X-Mailer: git-send-email 1.7.4.1 DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrMLMWRmVeSWpSXmKPExsVy+t8zLd3ilQcDDG78sLG48vU9mwOjx/3u 40wBjFFcNimpOZllqUX6dglcGbduPGYrmKFecfTCYrYGxu/yXYwcHBICJhJLet26GDmBTDGJ C/fWs3UxcnEICSxjlOg+s5ERpubyxziI+HRGiQ9fJ0IVrWeSOH2onRGkm01AVWLiivtsILaI gKlEx6SlLCA2s0ChxMKep2C2sICDxN51z5lBbBag+u9fj4DFeQWcJU69aWCDuEJBYsG9t2wQ NQIS3yYfYoE4QlZi0wFmkL0SAnvYJFb8mskMUS8pcXDFDZYJjIILGBlWMYqmFiQXFCel5xrq FSfmFpfmpesl5+duYoSElNQOxpUNFocYBTgYlXh4Fe4eCBBiTSwrrsw9xCjBwawkwtvRdzBA iDclsbIqtSg/vqg0J7X4EKMP0CUTmaVEk/OB4Z5XEm9obGBsaGhpaGZqaWqAQ1hJnLfZIyVA SCA9sSQ1OzW1ILUIZhwTB6dUAyP3vr4C2fRVvC0SubrHLt05bvSKJ6w5Q9FZrCSNZz/30UIO hf+c837tMGOvPfObqeJYlbKwhoOHCHPzWt8ANt/jZ8//LN7qNWeK5WcxDcU2kydeCT8/7iwR Z/1T9qnVbL37y5M7ExYsur3+/QVT01Pnvi50i0sS9VybFXvh506nFaLZCi+0gpVYijMSDbWY i4oTAZ+fw8FWAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrMLMWRmVeSWpSXmKPExsVy+t9jQd3ilQcDDC73Gltc+fqezYHR4373 caYAxqgGRpuM1MSU1CKF1Lzk/JTMvHRbJe/geOd4UzMDQ11DSwtzJYW8xNxUWyUXnwBdt8wc oLFKCmWJOaVAoYDE4mIlfTtME0JD3HQtYBojdH1DguB6jAzQQMI6xoxbNx6zFcxQrzh6YTFb A+N3+S5GDg4JAROJyx/juhg5gUwxiQv31rN1MXJxCAlMZ5T48HUilLOeSeL0oXZGkCo2AVWJ iSvus4HYIgKmEh2TlrKA2MwChRILe56C2cICDhJ71z1nBrFZgOq/fz0CFucVcJY49aaBDWKb gsSCe2/ZJjByL2BkWMUomlqQXFCclJ5rqFecmFtcmpeul5yfu4kRHLLPpHYwrmywOMQowMGo xMOrcPdAgBBrYllxZe4hRgkOZiUR3o6+gwFCvCmJlVWpRfnxRaU5qcWHGH2Atk9klhJNzgfG U15JvKGxiZmRpZGZsYm5sTEOYSVx3maPlAAhgfTEktTs1NSC1CKYcUwcnFINjMd/Jif+Pve7 p+GaJa+cximGgvn2ijLlexQSjc8x8mqw962U/LS1dfueqfYbevaebQ1anFrSt3Tjng2OC+dJ F7SXxh5bzHqIcfPBKULV0WphU1qmB+zKqde3iJw246v7ZJ5pD4t8VjzWX31QuUU+4+IJg7/H eRanvrgpsqCq8s0Wrc2zjpqu/KDEUpyRaKjFXFScCAC17q/ehgIAAA== X-CFilter-Loop: Reflected Cc: kyungmin.park@samsung.com, sw0312.kim@samsung.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org With this patch, When dma_buf_unmap_attachment is called, the pages of sgt aren't unmapped from iommu table. Instead, when dma_buf_detach is called, that would be done. And also removes exynos_get_sgt function used to get clone sgt and uses attachment's sgt instead. This patch would resolve performance deterioration issue when v4l2-based driver is using the buffer imported from gem. This change is derived from videobuf2-dma-contig.c Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 104 +++++++++++++++++++-------- 1 files changed, 73 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index 539da9f..61d5a84 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c @@ -30,63 +30,107 @@ #include -static struct sg_table *exynos_get_sgt(struct drm_device *drm_dev, - struct exynos_drm_gem_buf *buf) +struct exynos_drm_dmabuf_attachment { + struct sg_table sgt; + enum dma_data_direction dir; +}; + +static int exynos_gem_attach_dma_buf(struct dma_buf *dmabuf, + struct device *dev, + struct dma_buf_attachment *attach) { - struct sg_table *sgt = NULL; - int ret; + struct exynos_drm_dmabuf_attachment *exynos_attach; - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); - if (!sgt) - goto out; + exynos_attach = kzalloc(sizeof(*exynos_attach), GFP_KERNEL); + if (!exynos_attach) + return -ENOMEM; - ret = dma_get_sgtable(drm_dev->dev, sgt, buf->kvaddr, - buf->dma_addr, buf->size); - if (ret < 0) { - DRM_ERROR("failed to get sgtable.\n"); - goto err_free_sgt; - } + exynos_attach->dir = DMA_NONE; + attach->priv = exynos_attach; - return sgt; + return 0; +} -err_free_sgt: - kfree(sgt); - sgt = NULL; -out: - return NULL; +static void exynos_gem_detach_dma_buf(struct dma_buf *dmabuf, + struct dma_buf_attachment *attach) +{ + struct exynos_drm_dmabuf_attachment *exynos_attach = attach->priv; + struct sg_table *sgt; + + if (!exynos_attach) + return; + + sgt = &exynos_attach->sgt; + + if (exynos_attach->dir != DMA_NONE) + dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, + exynos_attach->dir); + + sg_free_table(sgt); + kfree(exynos_attach); + attach->priv = NULL; } static struct sg_table * exynos_gem_map_dma_buf(struct dma_buf_attachment *attach, enum dma_data_direction dir) { + struct exynos_drm_dmabuf_attachment *exynos_attach = attach->priv; struct exynos_drm_gem_obj *gem_obj = attach->dmabuf->priv; struct drm_device *dev = gem_obj->base.dev; struct exynos_drm_gem_buf *buf; + struct scatterlist *rd, *wr; struct sg_table *sgt = NULL; - int nents; + unsigned int i; + int nents, ret; DRM_DEBUG_PRIME("%s\n", __FILE__); + if (WARN_ON(dir == DMA_NONE)) + return ERR_PTR(-EINVAL); + + /* just return current sgt if already requested. */ + if (exynos_attach->dir == dir) + return &exynos_attach->sgt; + + /* reattaching is not allowed. */ + if (WARN_ON(exynos_attach->dir != DMA_NONE)) + return ERR_PTR(-EBUSY); + buf = gem_obj->buffer; if (!buf) { DRM_ERROR("buffer is null.\n"); - return sgt; + return ERR_PTR(-ENOMEM); + } + + sgt = &exynos_attach->sgt; + + ret = sg_alloc_table(sgt, buf->sgt->orig_nents, GFP_KERNEL); + if (ret) { + DRM_ERROR("failed to alloc sgt.\n"); + return ERR_PTR(-ENOMEM); } mutex_lock(&dev->struct_mutex); - sgt = exynos_get_sgt(dev, buf); - if (!sgt) - goto err_unlock; + rd = buf->sgt->sgl; + wr = sgt->sgl; + for (i = 0; i < sgt->orig_nents; ++i) { + sg_set_page(wr, sg_page(rd), rd->length, rd->offset); + rd = sg_next(rd); + wr = sg_next(wr); + } - nents = dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir); + nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir); if (!nents) { DRM_ERROR("failed to map sgl with iommu.\n"); - sgt = NULL; + sgt = ERR_PTR(-EIO); goto err_unlock; } + exynos_attach->dir = dir; + attach->priv = exynos_attach; + DRM_DEBUG_PRIME("buffer size = 0x%lx\n", buf->size); err_unlock: @@ -98,11 +142,7 @@ static void exynos_gem_unmap_dma_buf(struct dma_buf_attachment *attach, struct sg_table *sgt, enum dma_data_direction dir) { - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); - - sg_free_table(sgt); - kfree(sgt); - sgt = NULL; + /* Nothing to do. */ } static void exynos_dmabuf_release(struct dma_buf *dmabuf) @@ -164,6 +204,8 @@ static int exynos_gem_dmabuf_mmap(struct dma_buf *dma_buf, } static struct dma_buf_ops exynos_dmabuf_ops = { + .attach = exynos_gem_attach_dma_buf, + .detach = exynos_gem_detach_dma_buf, .map_dma_buf = exynos_gem_map_dma_buf, .unmap_dma_buf = exynos_gem_unmap_dma_buf, .kmap = exynos_gem_dmabuf_kmap,