diff options
author | Marcin Slusarz <marcin.slusarz@gmail.com> | 2011-09-09 08:16:42 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-11-09 17:58:53 -0500 |
commit | 5e60ee780e792efe6dce97eceb110b1d30bab850 (patch) | |
tree | e27495ae3d1ba32526eea93e37eefac685761f0b /drivers/gpu | |
parent | 7b4b98fa0c4d3a975b36bfe9984e4cd117f2ddff (diff) |
drm/nouveau: initialize chan->fence.lock before use
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>
Cc: stable@kernel.org
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_channel.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fence.c | 2 |
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 a319d5646ea9..bb6ec9ef8676 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -158,6 +158,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, | |||
158 | INIT_LIST_HEAD(&chan->nvsw.vbl_wait); | 158 | INIT_LIST_HEAD(&chan->nvsw.vbl_wait); |
159 | INIT_LIST_HEAD(&chan->nvsw.flip); | 159 | INIT_LIST_HEAD(&chan->nvsw.flip); |
160 | INIT_LIST_HEAD(&chan->fence.pending); | 160 | INIT_LIST_HEAD(&chan->fence.pending); |
161 | spin_lock_init(&chan->fence.lock); | ||
161 | 162 | ||
162 | /* setup channel's memory and vm */ | 163 | /* setup channel's memory and vm */ |
163 | ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle); | 164 | ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 81116cfea275..2f6daae68b9d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
@@ -539,8 +539,6 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) | |||
539 | return ret; | 539 | return ret; |
540 | } | 540 | } |
541 | 541 | ||
542 | INIT_LIST_HEAD(&chan->fence.pending); | ||
543 | spin_lock_init(&chan->fence.lock); | ||
544 | atomic_set(&chan->fence.last_sequence_irq, 0); | 542 | atomic_set(&chan->fence.last_sequence_irq, 0); |
545 | return 0; | 543 | return 0; |
546 | } | 544 | } |