diff options
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fence.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_semaphore.c | 137 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_test.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 1 |
10 files changed, 30 insertions, 149 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index ecc29bc1cbe..7e7ac3d6e76 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 9cd2657eb2c..107b2177e6c 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 d02f13fdaa6..478b51ea4d8 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 cc7f16ab257..45164e10125 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 | */ |
437 | struct radeon_ring; | ||
438 | |||
439 | #define RADEON_SEMAPHORE_BO_SIZE 256 | ||
440 | |||
441 | struct radeon_semaphore_driver { | ||
442 | rwlock_t lock; | ||
443 | struct list_head bo; | ||
444 | }; | ||
445 | |||
446 | struct radeon_semaphore_bo; | ||
447 | |||
448 | /* everything here is constant */ | 437 | /* everything here is constant */ |
449 | struct radeon_semaphore { | 438 | struct 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 | ||
456 | struct 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 | |||
464 | void radeon_semaphore_driver_fini(struct radeon_device *rdev); | ||
465 | int radeon_semaphore_create(struct radeon_device *rdev, | 444 | int radeon_semaphore_create(struct radeon_device *rdev, |
466 | struct radeon_semaphore **semaphore); | 445 | struct radeon_semaphore **semaphore); |
467 | void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, | 446 | void 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); |
475 | void radeon_semaphore_free(struct radeon_device *rdev, | 454 | void 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 b827b2e578f..48876c11a4a 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 14dbc287cac..3a49311fc71 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 dbde874b2e5..1bc5513a529 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 | ||
34 | static 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 | |||
72 | static 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 | |||
81 | void 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 | ||
100 | int radeon_semaphore_create(struct radeon_device *rdev, | 35 | int 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 | ||
108 | retry: | 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 | ||
137 | void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, | 57 | void 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 | ||
143 | void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, | 64 | void 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 | ||
202 | void radeon_semaphore_free(struct radeon_device *rdev, | 124 | void 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 | |||
214 | void 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 dc5dcf483aa..b0573876279 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 | ||
318 | out_cleanup: | 318 | out_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 | ||
438 | out_cleanup: | 438 | out_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 a8b001641e4..40f82e22a62 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 779f0b604fa..be3b9fd6c93 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); |