1 From bb4091558228ff4a3e02328c931e683fc7f08722 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Christian=20K=C3=B6nig?= <deathsimple@vodafone.de>
3 Date: Sun, 3 Jun 2012 16:09:43 +0200
4 Subject: drm/radeon: fix vm deadlocks on cayman
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
9 From: Christian König <deathsimple@vodafone.de>
11 commit bb4091558228ff4a3e02328c931e683fc7f08722 upstream.
13 Locking mutex in different orders just screams for
14 deadlocks, and some testing showed that it is actually
15 quite easy to trigger them.
17 Signed-off-by: Christian König <deathsimple@vodafone.de>
18 Reviewed-by: Jerome Glisse <jglisse@redhat.com>
19 Signed-off-by: Dave Airlie <airlied@redhat.com>
20 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
23 drivers/gpu/drm/radeon/radeon_gart.c | 19 ++++++++++++-------
24 1 file changed, 12 insertions(+), 7 deletions(-)
26 --- a/drivers/gpu/drm/radeon/radeon_gart.c
27 +++ b/drivers/gpu/drm/radeon/radeon_gart.c
28 @@ -478,12 +478,18 @@ int radeon_vm_bo_add(struct radeon_devic
30 mutex_lock(&vm->mutex);
31 if (last_pfn > vm->last_pfn) {
32 - /* grow va space 32M by 32M */
33 - unsigned align = ((32 << 20) >> 12) - 1;
34 + /* release mutex and lock in right order */
35 + mutex_unlock(&vm->mutex);
36 radeon_mutex_lock(&rdev->cs_mutex);
37 - radeon_vm_unbind_locked(rdev, vm);
38 + mutex_lock(&vm->mutex);
39 + /* and check again */
40 + if (last_pfn > vm->last_pfn) {
41 + /* grow va space 32M by 32M */
42 + unsigned align = ((32 << 20) >> 12) - 1;
43 + radeon_vm_unbind_locked(rdev, vm);
44 + vm->last_pfn = (last_pfn + align) & ~align;
46 radeon_mutex_unlock(&rdev->cs_mutex);
47 - vm->last_pfn = (last_pfn + align) & ~align;
51 @@ -597,8 +603,8 @@ int radeon_vm_bo_rmv(struct radeon_devic
55 - mutex_lock(&vm->mutex);
56 radeon_mutex_lock(&rdev->cs_mutex);
57 + mutex_lock(&vm->mutex);
58 radeon_vm_bo_update_pte(rdev, vm, bo, NULL);
59 radeon_mutex_unlock(&rdev->cs_mutex);
60 list_del(&bo_va->vm_list);
61 @@ -643,9 +649,8 @@ void radeon_vm_fini(struct radeon_device
62 struct radeon_bo_va *bo_va, *tmp;
65 - mutex_lock(&vm->mutex);
67 radeon_mutex_lock(&rdev->cs_mutex);
68 + mutex_lock(&vm->mutex);
69 radeon_vm_unbind_locked(rdev, vm);
70 radeon_mutex_unlock(&rdev->cs_mutex);