summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorMarcin Slusarz <marcin.slusarz@gmail.com>2011-09-09 14:16:42 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-21 14:31:16 -0800
commit53b6b123d40eda9bde41232b2c76d0e1e896b83d (patch)
tree4056b1b4436e459460d92af85ab092ec0c38ab60 /drivers/gpu
parent1db61fd3401a6520375293de302b3a9034edca1b (diff)
drm/nouveau: initialize chan->fence.lock before use
commit 5e60ee780e792efe6dce97eceb110b1d30bab850 upstream. Fence lock needs to be initialized before any call to nouveau_channel_put because it calls nouveau_channel_idle->nouveau_fence_update which uses fence lock. BUG: spinlock bad magic on CPU#0, test/24134 lock: ffff88019f90dba8, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0 Pid: 24134, comm: test Not tainted 3.0.0-nv+ #800 Call Trace: spin_bug+0x9c/0xa3 do_raw_spin_lock+0x29/0x13c _raw_spin_lock+0x1e/0x22 nouveau_fence_update+0x2d/0xf1 nouveau_channel_idle+0x22/0xa0 nouveau_channel_put_unlocked+0x84/0x1bd nouveau_channel_put+0x20/0x24 nouveau_channel_alloc+0x4ec/0x585 nouveau_ioctl_fifo_alloc+0x50/0x130 drm_ioctl+0x289/0x361 do_vfs_ioctl+0x4dd/0x52c sys_ioctl+0x42/0x65 system_call_fastpath+0x16/0x1b It's easily triggerable from userspace. Additionally remove double initialization of chan->fence.pending. Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_channel.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c2
2 files changed, 1 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
index a7583a8ddb01..d31d355f5ed0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -159,6 +159,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
INIT_LIST_HEAD(&chan->nvsw.vbl_wait);
INIT_LIST_HEAD(&chan->nvsw.flip);
INIT_LIST_HEAD(&chan->fence.pending);
+ spin_lock_init(&chan->fence.lock);
/* Allocate DMA push buffer */
chan->pushbuf_bo = nouveau_channel_user_pushbuf_alloc(dev);
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 7347075ca5b8..56f06b0cfdb6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -542,8 +542,6 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
return ret;
}
- INIT_LIST_HEAD(&chan->fence.pending);
- spin_lock_init(&chan->fence.lock);
atomic_set(&chan->fence.last_sequence_irq, 0);
return 0;
}