diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-10-05 16:53:48 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-12-03 15:05:10 +1000 |
commit | 6a6b73f254123851f7f73ab5e57344a569d6a0ab (patch) | |
tree | 5db28f577f0a7b15525aeef57d45a34ea4366bb8 /drivers/gpu/drm/nouveau/nouveau_bo.c | |
parent | ceed5f30bf0f515b52246230e5faacf89983fd8f (diff) |
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.c | 15 |
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 c41e1c200ef..d8817b4bb18 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 |