From patchwork Fri Nov 16 10:01:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Inki Dae X-Patchwork-Id: 1754101 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 0A7DB4005F for ; Fri, 16 Nov 2012 10:01:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D096FE5CC0 for ; Fri, 16 Nov 2012 02:01:32 -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 A04A0E5BFB for ; Fri, 16 Nov 2012 02:01:18 -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 <0MDK00F98RTU1C50@mailout4.samsung.com> for dri-devel@lists.freedesktop.org; Fri, 16 Nov 2012 19:01:17 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [203.254.230.43]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 5C.33.01231.DEE06A05; Fri, 16 Nov 2012 19:01:17 +0900 (KST) X-AuditID: cbfee61a-b7fa66d0000004cf-fb-50a60eedbd34 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 5B.33.01231.CEE06A05; Fri, 16 Nov 2012 19:01:16 +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 <0MDK00G8IRU42R40@mmp2.samsung.com> for dri-devel@lists.freedesktop.org; Fri, 16 Nov 2012 19:01:16 +0900 (KST) From: Inki Dae To: airlied@linux.ie, dri-devel@lists.freedesktop.org Subject: [PATCH v3] drm/exynos: add vm_ops to specific gem mmaper Date: Fri, 16 Nov 2012 19:01:16 +0900 Message-id: <1353060076-20776-1-git-send-email-inki.dae@samsung.com> X-Mailer: git-send-email 1.7.4.1 In-reply-to: <1352956993-2048-1-git-send-email-inki.dae@samsung.com> References: <1352956993-2048-1-git-send-email-inki.dae@samsung.com> DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrNLMWRmVeSWpSXmKPExsVy+t8zbd23fMsCDOZ8Yre48vU9mwOjx/3u 40wBjFFcNimpOZllqUX6dglcGQ/3dbIXfFKsuDS1lbGB8YN0FyMHh4SAicSJV/pdjJxAppjE hXvr2boYuTiEBJYxSnz795QFImEi8bvhOAtEYjqjxPUDa5ghnPVMEi2z17CCVLEJqEpMXHGf DcQWETCV6Ji0FKybWaBQYmEPxCRhAUeJH7unMYPYLED1k8/MZgKxeQVcJDYc28oGsU1BYsG9 t2A2J1B88oHr7CCXCgk4S7ROsYFoFZD4NvkQC8QDshKbDoCdIyFwmU1i/vwVTBBjJCUOrrjB MoFReAEjwypG0dSC5ILipPRcQ73ixNzi0rx0veT83E2MkBCU2sG4ssHiEKMAB6MSD6/g7aUB QqyJZcWVuYcYJTiYlUR4q1iXBQjxpiRWVqUW5ccXleakFh9i9AG6ZCKzlGhyPjA+8kriDY0N jA0NLQ3NTC1NDXAIK4nzNnukBAgJpCeWpGanphakFsGMY+LglGpgdDBde2XVgUdb9/Eei7/j PtnIcKZaWcThbF3xzI5DjJP1dCWOLRCY92TvjLbj3FNLfddf+Powlrsma5W+a2t34bKrJzL5 f2eay13r3WIT99M2J+F47VSRtGUpKuY1zVe97rkLGYmW7tx2MuZXS/JnsR6x/S9PfN2y2f1/ k46itPfmxT3HTsgYKLEUZyQaajEXFScCABQdX8ZuAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupmkeLIzCtJLcpLzFFi42I5/e+xoO4bvmUBBsc6rC2ufH3P5sDocb/7 OFMAY1QDo01GamJKapFCal5yfkpmXrqtkndwvHO8qZmBoa6hpYW5kkJeYm6qrZKLT4CuW2YO 0FglhbLEnFKgUEBicbGSvh2mCaEhbroWMI0Rur4hQXA9RgZoIGEdY8bDfZ3sBZ8UKy5NbWVs YPwg3cXIySEhYCLxu+E4C4QtJnHh3nq2LkYuDiGB6YwS1w+sYYZw1jNJtMxewwpSxSagKjFx xX02EFtEwFSiY9JSsG5mgUKJhT1PwWxhAUeJH7unMYPYLED1k8/MZgKxeQVcJDYc28oGsU1B YsG9t2A2J1B88oHr7F2MHEDLnCVap9hMYORdwMiwilE0tSC5oDgpPddQrzgxt7g0L10vOT93 EyM4xJ9J7WBc2WBxiFGAg1GJh1fw9tIAIdbEsuLK3EOMEhzMSiK8VazLAoR4UxIrq1KL8uOL SnNSiw8x+gAdNZFZSjQ5Hxh/eSXxhsYmZkaWRmbGJubGxjiElcR5mz1SAoQE0hNLUrNTUwtS i2DGMXFwSjUwlvDP31PXnpnz5a/3pmNbXvQqL36gvOT56sWv3lZGG12OrN56587//15TXxzR urv9a1SLTlzKy8PyX+JTl8QcleP7Vdi3NsZQMHmL+ZUv4eJbufX3KolV2iesW1nweOm/t9rZ b2+ZO978qPD1f3cCuzRjk5BpTEXp9DgfmQ+XN2ZX5He89ncuUWIpzkg01GIuKk4EAF0KT2qe AgAA 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 Changelog v3: use drm_file's file object instead of gem object's - gem object's file represents the shmem storage so process-unique file object should be used instead. Changelog v2: call mutex_lock before drm_vm_open_locked is called. Changelog v1: This patch makes it takes a reference to gem object when specific gem mmap is requested. For this, it sets dev->driver->gem_vm_ops to vma->vm_ops. 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: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 75 ++++++++++++++++++++++++++++-- 1 files changed, 70 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 50d73f1..fdabb0f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -365,17 +365,53 @@ int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data, &args->offset); } +static struct drm_file *exynos_drm_find_drm_file(struct drm_device *drm_dev, + struct file *filp) +{ + struct drm_file *file_priv; + + mutex_lock(&drm_dev->struct_mutex); + + /* find current process's drm_file from filelist. */ + list_for_each_entry(file_priv, &drm_dev->filelist, lhead) { + if (file_priv->filp == filp) { + mutex_unlock(&drm_dev->struct_mutex); + return file_priv; + } + } + + mutex_unlock(&drm_dev->struct_mutex); + WARN_ON(1); + + return ERR_PTR(-EFAULT); +} + static int exynos_drm_gem_mmap_buffer(struct file *filp, struct vm_area_struct *vma) { struct drm_gem_object *obj = filp->private_data; struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); + struct drm_device *drm_dev = obj->dev; struct exynos_drm_gem_buf *buffer; + struct drm_file *file_priv; unsigned long vm_size; + int ret; DRM_DEBUG_KMS("%s\n", __FILE__); vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; + vma->vm_private_data = obj; + vma->vm_ops = drm_dev->driver->gem_vm_ops; + + /* restore it to driver's fops. */ + filp->f_op = fops_get(drm_dev->driver->fops); + + file_priv = exynos_drm_find_drm_file(drm_dev, filp); + if (IS_ERR(file_priv)) + return PTR_ERR(file_priv); + + /* restore it to drm_file. */ + filp->private_data = file_priv; update_vm_cache_attr(exynos_gem_obj, vma); @@ -391,9 +427,25 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, if (vm_size > buffer->size) return -EINVAL; - return dma_mmap_attrs(obj->dev->dev, vma, buffer->kvaddr, + ret = dma_mmap_attrs(drm_dev->dev, vma, buffer->kvaddr, buffer->dma_addr, buffer->size, &buffer->dma_attrs); + if (ret < 0) { + DRM_ERROR("failed to mmap.\n"); + return ret; + } + + /* + * take a reference to this mapping of the object. And this reference + * is unreferenced by the corresponding vm_close call. + */ + drm_gem_object_reference(obj); + + mutex_lock(&drm_dev->struct_mutex); + drm_vm_open_locked(drm_dev, vma); + mutex_unlock(&drm_dev->struct_mutex); + + return 0; } static const struct file_operations exynos_drm_gem_fops = { @@ -420,16 +472,29 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - obj->filp->f_op = &exynos_drm_gem_fops; - obj->filp->private_data = obj; + /* + * Set specific mmper's fops. And it will be restored by + * exynos_drm_gem_mmap_buffer to dev->driver->fops. + * This is used to call specific mapper temporarily. + */ + file_priv->filp->f_op = &exynos_drm_gem_fops; - addr = vm_mmap(obj->filp, 0, args->size, + /* + * Set gem object to private_data so that specific mmaper + * can get the gem object. And it will be restored by + * exynos_drm_gem_mmap_buffer to drm_file. + */ + file_priv->filp->private_data = obj; + + addr = vm_mmap(file_priv->filp, 0, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, 0); drm_gem_object_unreference_unlocked(obj); - if (IS_ERR((void *)addr)) + if (IS_ERR((void *)addr)) { + file_priv->filp->private_data = file_priv; return PTR_ERR((void *)addr); + } args->mapped = addr;