summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nouveau_bo.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-10-05 10:53:48 +0400
committerBen Skeggs <bskeggs@redhat.com>2010-12-03 08:05:10 +0300
commit6a6b73f254123851f7f73ab5e57344a569d6a0ab (patch)
tree5db28f577f0a7b15525aeef57d45a34ea4366bb8 /drivers/gpu/drm/nouveau/nouveau_bo.c
parentceed5f30bf0f515b52246230e5faacf89983fd8f (diff)
downloadlinux-6a6b73f254123851f7f73ab5e57344a569d6a0ab.tar.xz
drm/nouveau: add per-channel mutex, use to lock access to drm's channel
This fixes a race condition between fbcon acceleration and TTM buffer moves. To reproduce: - start X - switch to vt and "while (true); do dmesg; done" - switch to another vt and "sleep 2 && cat /path/to/debugfs/dri/0/evict_vram" - switch back to vt running dmesg We don't make use of this on any other channel yet, they're currently protected by drm_global_mutex. This will change in the near future. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_bo.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index c41e1c200ef5..d8817b4bb189 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -683,17 +683,24 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
int ret;
chan = nvbo->channel;
- if (!chan || nvbo->no_vm)
+ if (!chan || nvbo->no_vm) {
chan = dev_priv->channel;
+ mutex_lock(&chan->mutex);
+ }
if (dev_priv->card_type < NV_50)
ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem);
else
ret = nv50_bo_move_m2mf(chan, bo, &bo->mem, new_mem);
- if (ret)
- return ret;
+ if (ret == 0) {
+ ret = nouveau_bo_move_accel_cleanup(chan, nvbo, evict,
+ no_wait_reserve,
+ no_wait_gpu, new_mem);
+ }
- return nouveau_bo_move_accel_cleanup(chan, nvbo, evict, no_wait_reserve, no_wait_gpu, new_mem);
+ if (chan == dev_priv->channel)
+ mutex_unlock(&chan->mutex);
+ return ret;
}
static int