diff options
author | Rob Clark <robdclark@gmail.com> | 2015-05-15 09:19:36 -0400 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2015-05-15 09:28:27 -0400 |
commit | 774449ebcb18bae146e2b6f6d012b46e64a095b9 (patch) | |
tree | 4d15925bc58522e2871c69e20bbce6dea00a14c6 /drivers | |
parent | ec1936eb099bb8c1c7a32b9ac4be128e1e68e2d9 (diff) | |
download | linux-774449ebcb18bae146e2b6f6d012b46e64a095b9.tar.gz linux-774449ebcb18bae146e2b6f6d012b46e64a095b9.tar.bz2 linux-774449ebcb18bae146e2b6f6d012b46e64a095b9.zip |
drm/msm: fix locking inconsistencies in gpu->destroy()
In error paths, this was being called without struct_mutex held.
Leading to panics like:
msm 1a00000.qcom,mdss_mdp: No memory protection without IOMMU
Kernel panic - not syncing: BUG!
CPU: 0 PID: 1409 Comm: cat Not tainted 4.0.0-dirty #4
Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT)
Call trace:
[<ffffffc000089c78>] dump_backtrace+0x0/0x118
[<ffffffc000089da0>] show_stack+0x10/0x20
[<ffffffc0006686d4>] dump_stack+0x84/0xc4
[<ffffffc0006678b4>] panic+0xd0/0x210
[<ffffffc0003e1ce4>] drm_gem_object_free+0x5c/0x60
[<ffffffc000402870>] adreno_gpu_cleanup+0x60/0x80
[<ffffffc0004035a0>] a3xx_destroy+0x20/0x70
[<ffffffc0004036f4>] a3xx_gpu_init+0x84/0x108
[<ffffffc0004018b8>] adreno_load_gpu+0x58/0x190
[<ffffffc000419dac>] msm_open+0x74/0x88
[<ffffffc0003e0a48>] drm_open+0x168/0x400
[<ffffffc0003e7210>] drm_stub_open+0xa8/0x118
[<ffffffc0001a0e84>] chrdev_open+0x94/0x198
[<ffffffc000199f88>] do_dentry_open+0x208/0x310
[<ffffffc00019a4c4>] vfs_open+0x44/0x50
[<ffffffc0001aa26c>] do_last.isra.14+0x2c4/0xc10
[<ffffffc0001aac38>] path_openat+0x80/0x5e8
[<ffffffc0001ac354>] do_filp_open+0x2c/0x98
[<ffffffc00019b60c>] do_sys_open+0x13c/0x228
[<ffffffc00019b72c>] SyS_openat+0xc/0x18
CPU1: stopping
But there isn't any particularly good reason to hold struct_mutex for
teardown, so just standardize on calling it without the mutex held and
use the _unlocked() versions for GEM obj unref'ing
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/msm/adreno/adreno_gpu.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_ringbuffer.c | 2 |
3 files changed, 3 insertions, 3 deletions
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 94a5bee69fe7..bbdcab0a56c1 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -384,7 +384,7 @@ void adreno_gpu_cleanup(struct adreno_gpu *gpu) if (gpu->memptrs_bo) { if (gpu->memptrs_iova) msm_gem_put_iova(gpu->memptrs_bo, gpu->base.id); - drm_gem_object_unreference(gpu->memptrs_bo); + drm_gem_object_unreference_unlocked(gpu->memptrs_bo); } release_firmware(gpu->pm4); release_firmware(gpu->pfp); diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index cc6485ef2949..c80a6bee2b18 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -145,8 +145,8 @@ static int msm_unload(struct drm_device *dev) if (gpu) { mutex_lock(&dev->struct_mutex); gpu->funcs->pm_suspend(gpu); - gpu->funcs->destroy(gpu); mutex_unlock(&dev->struct_mutex); + gpu->funcs->destroy(gpu); } if (priv->vram.paddr) { diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index 8171537dd7d1..1f14b908b221 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -56,6 +56,6 @@ fail: void msm_ringbuffer_destroy(struct msm_ringbuffer *ring) { if (ring->bo) - drm_gem_object_unreference(ring->bo); + drm_gem_object_unreference_unlocked(ring->bo); kfree(ring); } |