aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2012-05-09 09:34:57 -0400
committerDave Airlie <airlied@redhat.com>2012-05-09 12:22:40 -0400
commita8c05940bd590d96229bc170a63f14a22fb9c803 (patch)
tree74619acfa5d70690b437d3477b14513caf22bbc2 /drivers/gpu
parentc3b7fe8b8a0b717f90a4a0c49cffae27e46e3fb7 (diff)
drm/radeon: simplify semaphore handling v2
Directly use the suballocator to get small chunks of memory. It's equally fast and doesn't crash when we encounter a GPU reset. v2: rebased on new SA interface. Signed-off-by: Christian König <deathsimple@vodafone.de> Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c1
-rw-r--r--drivers/gpu/drm/radeon/ni.c1
-rw-r--r--drivers/gpu/drm/radeon/r600.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon.h29
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_semaphore.c137
-rw-r--r--drivers/gpu/drm/radeon/radeon_test.c4
-rw-r--r--drivers/gpu/drm/radeon/rv770.c1
-rw-r--r--drivers/gpu/drm/radeon/si.c1
10 files changed, 30 insertions, 149 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index ecc29bc1cbe3..7e7ac3d6e76e 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3550,7 +3550,6 @@ void evergreen_fini(struct radeon_device *rdev)
3550 evergreen_pcie_gart_fini(rdev); 3550 evergreen_pcie_gart_fini(rdev);
3551 r600_vram_scratch_fini(rdev); 3551 r600_vram_scratch_fini(rdev);
3552 radeon_gem_fini(rdev); 3552 radeon_gem_fini(rdev);
3553 radeon_semaphore_driver_fini(rdev);
3554 radeon_fence_driver_fini(rdev); 3553 radeon_fence_driver_fini(rdev);
3555 radeon_agp_fini(rdev); 3554 radeon_agp_fini(rdev);
3556 radeon_bo_fini(rdev); 3555 radeon_bo_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 9cd2657eb2ca..107b2177e6c5 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1744,7 +1744,6 @@ void cayman_fini(struct radeon_device *rdev)
1744 cayman_pcie_gart_fini(rdev); 1744 cayman_pcie_gart_fini(rdev);
1745 r600_vram_scratch_fini(rdev); 1745 r600_vram_scratch_fini(rdev);
1746 radeon_gem_fini(rdev); 1746 radeon_gem_fini(rdev);
1747 radeon_semaphore_driver_fini(rdev);
1748 radeon_fence_driver_fini(rdev); 1747 radeon_fence_driver_fini(rdev);
1749 radeon_bo_fini(rdev); 1748 radeon_bo_fini(rdev);
1750 radeon_atombios_fini(rdev); 1749 radeon_atombios_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index d02f13fdaa66..478b51ea4d87 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2658,7 +2658,6 @@ void r600_fini(struct radeon_device *rdev)
2658 r600_vram_scratch_fini(rdev); 2658 r600_vram_scratch_fini(rdev);
2659 radeon_agp_fini(rdev); 2659 radeon_agp_fini(rdev);
2660 radeon_gem_fini(rdev); 2660 radeon_gem_fini(rdev);
2661 radeon_semaphore_driver_fini(rdev);
2662 radeon_fence_driver_fini(rdev); 2661 radeon_fence_driver_fini(rdev);
2663 radeon_bo_fini(rdev); 2662 radeon_bo_fini(rdev);
2664 radeon_atombios_fini(rdev); 2663 radeon_atombios_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index cc7f16ab257f..45164e101257 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -434,34 +434,13 @@ int radeon_mode_dumb_destroy(struct drm_file *file_priv,
434/* 434/*
435 * Semaphores. 435 * Semaphores.
436 */ 436 */
437struct radeon_ring;
438
439#define RADEON_SEMAPHORE_BO_SIZE 256
440
441struct radeon_semaphore_driver {
442 rwlock_t lock;
443 struct list_head bo;
444};
445
446struct radeon_semaphore_bo;
447
448/* everything here is constant */ 437/* everything here is constant */
449struct radeon_semaphore { 438struct radeon_semaphore {
450 struct list_head list; 439 struct radeon_sa_bo *sa_bo;
440 signed waiters;
451 uint64_t gpu_addr; 441 uint64_t gpu_addr;
452 uint32_t *cpu_ptr;
453 struct radeon_semaphore_bo *bo;
454}; 442};
455 443
456struct radeon_semaphore_bo {
457 struct list_head list;
458 struct radeon_ib *ib;
459 struct list_head free;
460 struct radeon_semaphore semaphores[RADEON_SEMAPHORE_BO_SIZE/8];
461 unsigned nused;
462};
463
464void radeon_semaphore_driver_fini(struct radeon_device *rdev);
465int radeon_semaphore_create(struct radeon_device *rdev, 444int radeon_semaphore_create(struct radeon_device *rdev,
466 struct radeon_semaphore **semaphore); 445 struct radeon_semaphore **semaphore);
467void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, 446void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
@@ -473,7 +452,8 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev,
473 bool sync_to[RADEON_NUM_RINGS], 452 bool sync_to[RADEON_NUM_RINGS],
474 int dst_ring); 453 int dst_ring);
475void radeon_semaphore_free(struct radeon_device *rdev, 454void radeon_semaphore_free(struct radeon_device *rdev,
476 struct radeon_semaphore *semaphore); 455 struct radeon_semaphore *semaphore,
456 struct radeon_fence *fence);
477 457
478/* 458/*
479 * GART structures, functions & helpers 459 * GART structures, functions & helpers
@@ -1540,7 +1520,6 @@ struct radeon_device {
1540 struct radeon_mman mman; 1520 struct radeon_mman mman;
1541 struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS]; 1521 struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS];
1542 wait_queue_head_t fence_queue; 1522 wait_queue_head_t fence_queue;
1543 struct radeon_semaphore_driver semaphore_drv;
1544 struct mutex ring_lock; 1523 struct mutex ring_lock;
1545 struct radeon_ring ring[RADEON_NUM_RINGS]; 1524 struct radeon_ring ring[RADEON_NUM_RINGS];
1546 struct radeon_ib_pool ib_pool; 1525 struct radeon_ib_pool ib_pool;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index b827b2e578f3..48876c11a4a9 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -732,11 +732,9 @@ int radeon_device_init(struct radeon_device *rdev,
732 mutex_init(&rdev->gem.mutex); 732 mutex_init(&rdev->gem.mutex);
733 mutex_init(&rdev->pm.mutex); 733 mutex_init(&rdev->pm.mutex);
734 mutex_init(&rdev->vram_mutex); 734 mutex_init(&rdev->vram_mutex);
735 rwlock_init(&rdev->semaphore_drv.lock);
736 INIT_LIST_HEAD(&rdev->gem.objects); 735 INIT_LIST_HEAD(&rdev->gem.objects);
737 init_waitqueue_head(&rdev->irq.vblank_queue); 736 init_waitqueue_head(&rdev->irq.vblank_queue);
738 init_waitqueue_head(&rdev->irq.idle_queue); 737 init_waitqueue_head(&rdev->irq.idle_queue);
739 INIT_LIST_HEAD(&rdev->semaphore_drv.bo);
740 /* initialize vm here */ 738 /* initialize vm here */
741 rdev->vm_manager.use_bitmap = 1; 739 rdev->vm_manager.use_bitmap = 1;
742 rdev->vm_manager.max_pfn = 1 << 20; 740 rdev->vm_manager.max_pfn = 1 << 20;
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 14dbc287cac7..3a49311fc711 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -140,7 +140,7 @@ static void radeon_fence_destroy(struct kref *kref)
140 fence = container_of(kref, struct radeon_fence, kref); 140 fence = container_of(kref, struct radeon_fence, kref);
141 fence->seq = RADEON_FENCE_NOTEMITED_SEQ; 141 fence->seq = RADEON_FENCE_NOTEMITED_SEQ;
142 if (fence->semaphore) 142 if (fence->semaphore)
143 radeon_semaphore_free(fence->rdev, fence->semaphore); 143 radeon_semaphore_free(fence->rdev, fence->semaphore, NULL);
144 kfree(fence); 144 kfree(fence);
145} 145}
146 146
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c
index dbde874b2e5e..1bc5513a5292 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -31,118 +31,40 @@
31#include "drm.h" 31#include "drm.h"
32#include "radeon.h" 32#include "radeon.h"
33 33
34static int radeon_semaphore_add_bo(struct radeon_device *rdev)
35{
36 struct radeon_semaphore_bo *bo;
37 unsigned long irq_flags;
38 uint64_t gpu_addr;
39 uint32_t *cpu_ptr;
40 int r, i;
41
42 bo = kmalloc(sizeof(struct radeon_semaphore_bo), GFP_KERNEL);
43 if (bo == NULL) {
44 return -ENOMEM;
45 }
46 INIT_LIST_HEAD(&bo->free);
47 INIT_LIST_HEAD(&bo->list);
48 bo->nused = 0;
49
50 r = radeon_ib_get(rdev, 0, &bo->ib, RADEON_SEMAPHORE_BO_SIZE);
51 if (r) {
52 dev_err(rdev->dev, "failed to get a bo after 5 retry\n");
53 kfree(bo);
54 return r;
55 }
56 gpu_addr = radeon_sa_bo_gpu_addr(bo->ib->sa_bo);
57 cpu_ptr = radeon_sa_bo_cpu_addr(bo->ib->sa_bo);
58 for (i = 0; i < (RADEON_SEMAPHORE_BO_SIZE/8); i++) {
59 bo->semaphores[i].gpu_addr = gpu_addr;
60 bo->semaphores[i].cpu_ptr = cpu_ptr;
61 bo->semaphores[i].bo = bo;
62 list_add_tail(&bo->semaphores[i].list, &bo->free);
63 gpu_addr += 8;
64 cpu_ptr += 2;
65 }
66 write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags);
67 list_add_tail(&bo->list, &rdev->semaphore_drv.bo);
68 write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags);
69 return 0;
70}
71
72static void radeon_semaphore_del_bo_locked(struct radeon_device *rdev,
73 struct radeon_semaphore_bo *bo)
74{
75 radeon_sa_bo_free(rdev, &bo->ib->sa_bo, NULL);
76 radeon_fence_unref(&bo->ib->fence);
77 list_del(&bo->list);
78 kfree(bo);
79}
80
81void radeon_semaphore_shrink_locked(struct radeon_device *rdev)
82{
83 struct radeon_semaphore_bo *bo, *n;
84
85 if (list_empty(&rdev->semaphore_drv.bo)) {
86 return;
87 }
88 /* only shrink if first bo has free semaphore */
89 bo = list_first_entry(&rdev->semaphore_drv.bo, struct radeon_semaphore_bo, list);
90 if (list_empty(&bo->free)) {
91 return;
92 }
93 list_for_each_entry_safe_continue(bo, n, &rdev->semaphore_drv.bo, list) {
94 if (bo->nused)
95 continue;
96 radeon_semaphore_del_bo_locked(rdev, bo);
97 }
98}
99 34
100int radeon_semaphore_create(struct radeon_device *rdev, 35int radeon_semaphore_create(struct radeon_device *rdev,
101 struct radeon_semaphore **semaphore) 36 struct radeon_semaphore **semaphore)
102{ 37{
103 struct radeon_semaphore_bo *bo;
104 unsigned long irq_flags;
105 bool do_retry = true;
106 int r; 38 int r;
107 39
108retry: 40 *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL);
109 *semaphore = NULL;
110 write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags);
111 list_for_each_entry(bo, &rdev->semaphore_drv.bo, list) {
112 if (list_empty(&bo->free))
113 continue;
114 *semaphore = list_first_entry(&bo->free, struct radeon_semaphore, list);
115 (*semaphore)->cpu_ptr[0] = 0;
116 (*semaphore)->cpu_ptr[1] = 0;
117 list_del(&(*semaphore)->list);
118 bo->nused++;
119 break;
120 }
121 write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags);
122
123 if (*semaphore == NULL) { 41 if (*semaphore == NULL) {
124 if (do_retry) {
125 do_retry = false;
126 r = radeon_semaphore_add_bo(rdev);
127 if (r)
128 return r;
129 goto retry;
130 }
131 return -ENOMEM; 42 return -ENOMEM;
132 } 43 }
133 44 r = radeon_sa_bo_new(rdev, &rdev->ib_pool.sa_manager,
45 &(*semaphore)->sa_bo, 8, 8, true);
46 if (r) {
47 kfree(*semaphore);
48 *semaphore = NULL;
49 return r;
50 }
51 (*semaphore)->waiters = 0;
52 (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo);
53 *((uint64_t*)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0;
134 return 0; 54 return 0;
135} 55}
136 56
137void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, 57void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
138 struct radeon_semaphore *semaphore) 58 struct radeon_semaphore *semaphore)
139{ 59{
60 --semaphore->waiters;
140 radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, false); 61 radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, false);
141} 62}
142 63
143void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, 64void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
144 struct radeon_semaphore *semaphore) 65 struct radeon_semaphore *semaphore)
145{ 66{
67 ++semaphore->waiters;
146 radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true); 68 radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true);
147} 69}
148 70
@@ -200,29 +122,16 @@ error:
200} 122}
201 123
202void radeon_semaphore_free(struct radeon_device *rdev, 124void radeon_semaphore_free(struct radeon_device *rdev,
203 struct radeon_semaphore *semaphore) 125 struct radeon_semaphore *semaphore,
126 struct radeon_fence *fence)
204{ 127{
205 unsigned long irq_flags; 128 if (semaphore == NULL) {
206 129 return;
207 write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags); 130 }
208 semaphore->bo->nused--; 131 if (semaphore->waiters > 0) {
209 list_add_tail(&semaphore->list, &semaphore->bo->free); 132 dev_err(rdev->dev, "semaphore %p has more waiters than signalers,"
210 radeon_semaphore_shrink_locked(rdev); 133 " hardware lockup imminent!\n", semaphore);
211 write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags);
212}
213
214void radeon_semaphore_driver_fini(struct radeon_device *rdev)
215{
216 struct radeon_semaphore_bo *bo, *n;
217 unsigned long irq_flags;
218
219 write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags);
220 /* we force to free everything */
221 list_for_each_entry_safe(bo, n, &rdev->semaphore_drv.bo, list) {
222 if (!list_empty(&bo->free)) {
223 dev_err(rdev->dev, "still in use semaphore\n");
224 }
225 radeon_semaphore_del_bo_locked(rdev, bo);
226 } 134 }
227 write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags); 135 radeon_sa_bo_free(rdev, &semaphore->sa_bo, fence);
136 kfree(semaphore);
228} 137}
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
index dc5dcf483aa3..b05738762790 100644
--- a/drivers/gpu/drm/radeon/radeon_test.c
+++ b/drivers/gpu/drm/radeon/radeon_test.c
@@ -317,7 +317,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev,
317 317
318out_cleanup: 318out_cleanup:
319 if (semaphore) 319 if (semaphore)
320 radeon_semaphore_free(rdev, semaphore); 320 radeon_semaphore_free(rdev, semaphore, NULL);
321 321
322 if (fence1) 322 if (fence1)
323 radeon_fence_unref(&fence1); 323 radeon_fence_unref(&fence1);
@@ -437,7 +437,7 @@ void radeon_test_ring_sync2(struct radeon_device *rdev,
437 437
438out_cleanup: 438out_cleanup:
439 if (semaphore) 439 if (semaphore)
440 radeon_semaphore_free(rdev, semaphore); 440 radeon_semaphore_free(rdev, semaphore, NULL);
441 441
442 if (fenceA) 442 if (fenceA)
443 radeon_fence_unref(&fenceA); 443 radeon_fence_unref(&fenceA);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index a8b001641e4b..40f82e22a621 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1278,7 +1278,6 @@ void rv770_fini(struct radeon_device *rdev)
1278 rv770_pcie_gart_fini(rdev); 1278 rv770_pcie_gart_fini(rdev);
1279 r600_vram_scratch_fini(rdev); 1279 r600_vram_scratch_fini(rdev);
1280 radeon_gem_fini(rdev); 1280 radeon_gem_fini(rdev);
1281 radeon_semaphore_driver_fini(rdev);
1282 radeon_fence_driver_fini(rdev); 1281 radeon_fence_driver_fini(rdev);
1283 radeon_agp_fini(rdev); 1282 radeon_agp_fini(rdev);
1284 radeon_bo_fini(rdev); 1283 radeon_bo_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 779f0b604fad..be3b9fd6c931 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -4109,7 +4109,6 @@ void si_fini(struct radeon_device *rdev)
4109 si_pcie_gart_fini(rdev); 4109 si_pcie_gart_fini(rdev);
4110 r600_vram_scratch_fini(rdev); 4110 r600_vram_scratch_fini(rdev);
4111 radeon_gem_fini(rdev); 4111 radeon_gem_fini(rdev);
4112 radeon_semaphore_driver_fini(rdev);
4113 radeon_fence_driver_fini(rdev); 4112 radeon_fence_driver_fini(rdev);
4114 radeon_bo_fini(rdev); 4113 radeon_bo_fini(rdev);
4115 radeon_atombios_fini(rdev); 4114 radeon_atombios_fini(rdev);