diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-10-05 02:53:48 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-12-03 00:05:10 -0500 |
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 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, | |||
683 | int ret; | 683 | int ret; |
684 | 684 | ||
685 | chan = nvbo->channel; | 685 | chan = nvbo->channel; |
686 | if (!chan || nvbo->no_vm) | 686 | if (!chan || nvbo->no_vm) { |
687 | chan = dev_priv->channel; | 687 | chan = dev_priv->channel; |
688 | mutex_lock(&chan->mutex); | ||
689 | } | ||
688 | 690 | ||
689 | if (dev_priv->card_type < NV_50) | 691 | if (dev_priv->card_type < NV_50) |
690 | ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem); | 692 | ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem); |
691 | else | 693 | else |
692 | ret = nv50_bo_move_m2mf(chan, bo, &bo->mem, new_mem); | 694 | ret = nv50_bo_move_m2mf(chan, bo, &bo->mem, new_mem); |
693 | if (ret) | 695 | if (ret == 0) { |
694 | return ret; | 696 | ret = nouveau_bo_move_accel_cleanup(chan, nvbo, evict, |
697 | no_wait_reserve, | ||
698 | no_wait_gpu, new_mem); | ||
699 | } | ||
695 | 700 | ||
696 | return nouveau_bo_move_accel_cleanup(chan, nvbo, evict, no_wait_reserve, no_wait_gpu, new_mem); | 701 | if (chan == dev_priv->channel) |
702 | mutex_unlock(&chan->mutex); | ||
703 | return ret; | ||
697 | } | 704 | } |
698 | 705 | ||
699 | static int | 706 | static int |