[PATCH] drm/exynos: fix deadlock issue at mmap
Inki Dae
inki.dae at samsung.com
Mon Sep 23 21:58:22 PDT 2013
Please, ignore this patch. This patch has still some problems. I will post
it later.
Thanks,
Inki Dae
> -----Original Message-----
> From: Inki Dae [mailto:inki.dae at samsung.com]
> Sent: Monday, September 23, 2013 7:43 PM
> To: airlied at linux.ie; dri-devel at lists.freedesktop.org
> Cc: Inki Dae; Kyungmin Park
> Subject: [PATCH] drm/exynos: fix deadlock issue at mmap
>
> This patch fixes the deadlock issue when another process requested
> mmap system call.
>
> This issue can incur the deadlock if another process sharing the same
> file called mmap system call between ->f_op pointer chaning and restoring.
>
> So this patch calls down_write(&mm->mmap_sem) before do_mmap_pgoff
> call and then up_write(&mm->mmap_sem) after do_mmap_pg_off call
> so that when another process called mmap system call, the process
> can wait for up_write() call until the ->f_op pointer is restored.
>
> Signed-off-by: Inki Dae <inki.dae at samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
> ---
> drivers/gpu/drm/exynos/exynos_drm_gem.c | 20 ++++++++++++++++++--
> 1 file changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c
> b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> index 49f9cd2..779c2d7 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> @@ -13,6 +13,7 @@
> #include <drm/drm_vma_manager.h>
>
> #include <linux/shmem_fs.h>
> +#include <linux/security.h>
> #include <drm/exynos_drm.h>
>
> #include "exynos_drm_drv.h"
> @@ -420,6 +421,7 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev,
> void *data,
> {
> struct drm_exynos_gem_mmap *args = data;
> struct drm_gem_object *obj;
> + struct mm_struct *mm = current->mm;
> unsigned long addr;
>
> if (!(dev->driver->driver_features & DRIVER_GEM)) {
> @@ -433,6 +435,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev,
> void *data,
> return -EINVAL;
> }
>
> + down_write(&mm->mmap_sem);
> +
> /*
> * We have to use gem object and its fops for specific mmaper,
> * but vm_mmap() can deliver only filp. So we have to change
> @@ -457,8 +461,17 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev,
> void *data,
> */
> file_priv->filp->private_data = obj;
>
> - addr = vm_mmap(file_priv->filp, 0, args->size,
> - PROT_READ | PROT_WRITE, MAP_SHARED, 0);
> + addr = security_mmap_file(file_priv->filp, PROT_READ | PROT_WRITE,
> + MAP_SHARED);
> + if (!addr) {
> + unsigned long populate;
> +
> + addr = do_mmap_pgoff(file_priv->filp, 0, args->size,
> + PROT_READ | PROT_WRITE,
> + MAP_SHARED, 0, &populate);
> + if (populate)
> + mm_populate(addr, populate);
> + }
>
> drm_gem_object_unreference(obj);
>
> @@ -469,10 +482,13 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device
*dev,
> void *data,
> file_priv->filp->private_data = file_priv;
> }
> mutex_unlock(&dev->struct_mutex);
> + up_write(&mm->mmap_sem);
> +
> return (int)addr;
> }
>
> mutex_unlock(&dev->struct_mutex);
> + up_write(&mm->mmap_sem);
>
> args->mapped = addr;
>
> --
> 1.7.9.5
More information about the dri-devel
mailing list