Changelog v2: Implement copy sgt code in exynos_get_sgt itself instead of calling sg_clone_table. Changelog v1: During map_dma_buf, a new sgt needs to be created before being mapped to another device's address space. Currently, this sgt is created by calling dma_get_sgtable which creates a sgt from pages. This will be time consuming if the map/unmap calls are done repeatedly for very large buffers. Instead, we can just use the sgt which was already created during buffer allocation and create the new sgt by copying the sgls from the existing sgt. And this patch is based on exynos-drm-next-iommu branch of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos Signed-off-by: Prathyush K <prathyush.k@xxxxxxxxxxx> --- drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 18 +++++++++++++++--- 1 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index d9307bd..91c7db1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c @@ -34,19 +34,31 @@ static struct sg_table *exynos_get_sgt(struct drm_device *drm_dev, struct exynos_drm_gem_buf *buf) { struct sg_table *sgt = NULL; + struct scatterlist *s, *s_out; + unsigned int i; int ret; + if (!buf->sgt) { + DRM_ERROR("no sg table.\n"); + goto out; + } + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); if (!sgt) goto out; - ret = dma_get_sgtable(drm_dev->dev, sgt, buf->kvaddr, - buf->dma_addr, buf->size); + ret = sg_alloc_table(sgt, buf->sgt->orig_nents, GFP_KERNEL); if (ret < 0) { - DRM_ERROR("failed to get sgtable.\n"); + DRM_ERROR("failed to alloc table\n"); goto err_free_sgt; } + s_out = sgt->sgl; + for_each_sg(buf->sgt->sgl, s, buf->sgt->orig_nents, i) { + sg_set_page(s_out, sg_page(s), s->length, s->offset); + s_out = sg_next(s_out); + } + return sgt; err_free_sgt: -- 1.7.0.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel