[4/4] drm/panfrost: Fix sleeping while atomic in panfrost_gem_open
diff mbox series

Message ID 20190819161204.3106-5-robh@kernel.org
State New
Headers show
Series
  • panfrost: Locking fixes
Related show

Commit Message

Rob Herring Aug. 19, 2019, 4:12 p.m. UTC
We can't hold the mm_lock spinlock as panfrost_mmu_map() can sleep:

BUG: sleeping function called from invalid context at kernel/locking/mutex.c:909
in_atomic(): 1, irqs_disabled(): 0, pid: 974, name: glmark2-es2-drm
1 lock held by glmark2-es2-drm/974:
CPU: 5 PID: 974 Comm: glmark2-es2-drm Tainted: G        W    L    5.3.0-rc1+ #94
Hardware name: 96boards Rock960 (DT)
Call trace:
 dump_backtrace+0x0/0x130
 show_stack+0x14/0x20
 dump_stack+0xc4/0x10c
 ___might_sleep+0x158/0x228
 __might_sleep+0x50/0x88
 __mutex_lock+0x58/0x800
 mutex_lock_interruptible_nested+0x1c/0x28
 drm_gem_shmem_get_pages+0x24/0xa0
 drm_gem_shmem_get_pages_sgt+0x48/0xd0
 panfrost_mmu_map+0x38/0xf8 [panfrost]
 panfrost_gem_open+0xc0/0xd8 [panfrost]
 drm_gem_handle_create_tail+0xe8/0x198
 drm_gem_handle_create+0x3c/0x50
 panfrost_gem_create_with_handle+0x70/0xa0 [panfrost]
 panfrost_ioctl_create_bo+0x48/0x80 [panfrost]
 drm_ioctl_kernel+0xb8/0x110
 drm_ioctl+0x244/0x3f0
 do_vfs_ioctl+0xbc/0x910
 ksys_ioctl+0x78/0xa8
 __arm64_sys_ioctl+0x1c/0x28
 el0_svc_common.constprop.0+0x90/0x168
 el0_svc_handler+0x28/0x78
 el0_svc+0x8/0xc

Fixes: 68337d0b8644 ("drm/panfrost: Restructure the GEM object creation")
Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Rob Herring <robh@kernel.org>
---
 drivers/gpu/drm/panfrost/panfrost_gem.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

Comments

Steven Price Aug. 22, 2019, 2:58 p.m. UTC | #1
On 19/08/2019 17:12, Rob Herring wrote:
> We can't hold the mm_lock spinlock as panfrost_mmu_map() can sleep:
> 
> BUG: sleeping function called from invalid context at kernel/locking/mutex.c:909
> in_atomic(): 1, irqs_disabled(): 0, pid: 974, name: glmark2-es2-drm
> 1 lock held by glmark2-es2-drm/974:
> CPU: 5 PID: 974 Comm: glmark2-es2-drm Tainted: G        W    L    5.3.0-rc1+ #94
> Hardware name: 96boards Rock960 (DT)
> Call trace:
>  dump_backtrace+0x0/0x130
>  show_stack+0x14/0x20
>  dump_stack+0xc4/0x10c
>  ___might_sleep+0x158/0x228
>  __might_sleep+0x50/0x88
>  __mutex_lock+0x58/0x800
>  mutex_lock_interruptible_nested+0x1c/0x28
>  drm_gem_shmem_get_pages+0x24/0xa0
>  drm_gem_shmem_get_pages_sgt+0x48/0xd0
>  panfrost_mmu_map+0x38/0xf8 [panfrost]
>  panfrost_gem_open+0xc0/0xd8 [panfrost]
>  drm_gem_handle_create_tail+0xe8/0x198
>  drm_gem_handle_create+0x3c/0x50
>  panfrost_gem_create_with_handle+0x70/0xa0 [panfrost]
>  panfrost_ioctl_create_bo+0x48/0x80 [panfrost]
>  drm_ioctl_kernel+0xb8/0x110
>  drm_ioctl+0x244/0x3f0
>  do_vfs_ioctl+0xbc/0x910
>  ksys_ioctl+0x78/0xa8
>  __arm64_sys_ioctl+0x1c/0x28
>  el0_svc_common.constprop.0+0x90/0x168
>  el0_svc_handler+0x28/0x78
>  el0_svc+0x8/0xc
> 
> Fixes: 68337d0b8644 ("drm/panfrost: Restructure the GEM object creation")
> Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
> Cc: David Airlie <airlied@linux.ie>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Signed-off-by: Rob Herring <robh@kernel.org>

Reviewed-by: Steven Price <steven.price@arm.com>

> ---
>  drivers/gpu/drm/panfrost/panfrost_gem.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
> index e084bc4e9083..acb07fe06580 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_gem.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
> @@ -65,16 +65,18 @@ static int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_p
>  	spin_lock(&priv->mm_lock);
>  	ret = drm_mm_insert_node_generic(&priv->mm, &bo->node,
>  					 size >> PAGE_SHIFT, align, color, 0);
> +	spin_unlock(&priv->mm_lock);
>  	if (ret)
> -		goto out;
> +		return ret;
>  
>  	if (!bo->is_heap) {
>  		ret = panfrost_mmu_map(bo);
> -		if (ret)
> +		if (ret) {
> +			spin_lock(&priv->mm_lock);
>  			drm_mm_remove_node(&bo->node);
> +			spin_unlock(&priv->mm_lock);
> +		}
>  	}
> -out:
> -	spin_unlock(&priv->mm_lock);
>  	return ret;
>  }
>  
>

Patch
diff mbox series

diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index e084bc4e9083..acb07fe06580 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -65,16 +65,18 @@  static int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_p
 	spin_lock(&priv->mm_lock);
 	ret = drm_mm_insert_node_generic(&priv->mm, &bo->node,
 					 size >> PAGE_SHIFT, align, color, 0);
+	spin_unlock(&priv->mm_lock);
 	if (ret)
-		goto out;
+		return ret;
 
 	if (!bo->is_heap) {
 		ret = panfrost_mmu_map(bo);
-		if (ret)
+		if (ret) {
+			spin_lock(&priv->mm_lock);
 			drm_mm_remove_node(&bo->node);
+			spin_unlock(&priv->mm_lock);
+		}
 	}
-out:
-	spin_unlock(&priv->mm_lock);
 	return ret;
 }