aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2012-05-09 09:34:45 -0400
committerDave Airlie <airlied@redhat.com>2012-05-09 12:22:14 -0400
commitd6999bc7b5f4b4554ebba5b48377903fa20198db (patch)
tree6dc61cf64362c4682d2bed9d591d8677376af795 /drivers/gpu/drm/radeon
parent133f4cb3365ef8e57c4837ffbe15de74684f6e19 (diff)
drm/radeon: replace the per ring mutex with a global one
A single global mutex for ring submissions seems sufficient. Signed-off-by: Christian König <deathsimple@vodafone.de> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c28
-rw-r--r--drivers/gpu/drm/radeon/radeon_semaphore.c42
5 files changed, 41 insertions, 45 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 82ffa6a05cc6..e99ea816d8c9 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -676,7 +676,6 @@ struct radeon_ring {
676 uint64_t gpu_addr; 676 uint64_t gpu_addr;
677 uint32_t align_mask; 677 uint32_t align_mask;
678 uint32_t ptr_mask; 678 uint32_t ptr_mask;
679 struct mutex mutex;
680 bool ready; 679 bool ready;
681 u32 ptr_reg_shift; 680 u32 ptr_reg_shift;
682 u32 ptr_reg_mask; 681 u32 ptr_reg_mask;
@@ -815,6 +814,7 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsign
815int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); 814int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw);
816void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *cp); 815void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *cp);
817void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *cp); 816void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *cp);
817void radeon_ring_undo(struct radeon_ring *ring);
818void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp); 818void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp);
819int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); 819int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
820void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring); 820void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring);
@@ -1534,6 +1534,7 @@ struct radeon_device {
1534 rwlock_t fence_lock; 1534 rwlock_t fence_lock;
1535 struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS]; 1535 struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS];
1536 struct radeon_semaphore_driver semaphore_drv; 1536 struct radeon_semaphore_driver semaphore_drv;
1537 struct mutex ring_lock;
1537 struct radeon_ring ring[RADEON_NUM_RINGS]; 1538 struct radeon_ring ring[RADEON_NUM_RINGS];
1538 struct radeon_ib_pool ib_pool; 1539 struct radeon_ib_pool ib_pool;
1539 struct radeon_irq irq; 1540 struct radeon_irq irq;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index ff28210dedec..3f6ff2a0bce2 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -724,8 +724,7 @@ int radeon_device_init(struct radeon_device *rdev,
724 * can recall function without having locking issues */ 724 * can recall function without having locking issues */
725 radeon_mutex_init(&rdev->cs_mutex); 725 radeon_mutex_init(&rdev->cs_mutex);
726 radeon_mutex_init(&rdev->ib_pool.mutex); 726 radeon_mutex_init(&rdev->ib_pool.mutex);
727 for (i = 0; i < RADEON_NUM_RINGS; ++i) 727 mutex_init(&rdev->ring_lock);
728 mutex_init(&rdev->ring[i].mutex);
729 mutex_init(&rdev->dc_hw_i2c_mutex); 728 mutex_init(&rdev->dc_hw_i2c_mutex);
730 if (rdev->family >= CHIP_R600) 729 if (rdev->family >= CHIP_R600)
731 spin_lock_init(&rdev->ih.lock); 730 spin_lock_init(&rdev->ih.lock);
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index caa55d68f319..7c3874589e3b 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -252,10 +252,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
252 252
253 mutex_lock(&rdev->ddev->struct_mutex); 253 mutex_lock(&rdev->ddev->struct_mutex);
254 mutex_lock(&rdev->vram_mutex); 254 mutex_lock(&rdev->vram_mutex);
255 for (i = 0; i < RADEON_NUM_RINGS; ++i) { 255 mutex_lock(&rdev->ring_lock);
256 if (rdev->ring[i].ring_obj)
257 mutex_lock(&rdev->ring[i].mutex);
258 }
259 256
260 /* gui idle int has issues on older chips it seems */ 257 /* gui idle int has issues on older chips it seems */
261 if (rdev->family >= CHIP_R600) { 258 if (rdev->family >= CHIP_R600) {
@@ -311,10 +308,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
311 308
312 rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; 309 rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE;
313 310
314 for (i = 0; i < RADEON_NUM_RINGS; ++i) { 311 mutex_unlock(&rdev->ring_lock);
315 if (rdev->ring[i].ring_obj)
316 mutex_unlock(&rdev->ring[i].mutex);
317 }
318 mutex_unlock(&rdev->vram_mutex); 312 mutex_unlock(&rdev->vram_mutex);
319 mutex_unlock(&rdev->ddev->struct_mutex); 313 mutex_unlock(&rdev->ddev->struct_mutex);
320} 314}
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 2eb4c6ed198a..a4d60ae524b1 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -346,9 +346,9 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi
346 if (ndw < ring->ring_free_dw) { 346 if (ndw < ring->ring_free_dw) {
347 break; 347 break;
348 } 348 }
349 mutex_unlock(&ring->mutex); 349 mutex_unlock(&rdev->ring_lock);
350 r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring)); 350 r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring));
351 mutex_lock(&ring->mutex); 351 mutex_lock(&rdev->ring_lock);
352 if (r) 352 if (r)
353 return r; 353 return r;
354 } 354 }
@@ -361,10 +361,10 @@ int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsig
361{ 361{
362 int r; 362 int r;
363 363
364 mutex_lock(&ring->mutex); 364 mutex_lock(&rdev->ring_lock);
365 r = radeon_ring_alloc(rdev, ring, ndw); 365 r = radeon_ring_alloc(rdev, ring, ndw);
366 if (r) { 366 if (r) {
367 mutex_unlock(&ring->mutex); 367 mutex_unlock(&rdev->ring_lock);
368 return r; 368 return r;
369 } 369 }
370 return 0; 370 return 0;
@@ -389,20 +389,25 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
389void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring) 389void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring)
390{ 390{
391 radeon_ring_commit(rdev, ring); 391 radeon_ring_commit(rdev, ring);
392 mutex_unlock(&ring->mutex); 392 mutex_unlock(&rdev->ring_lock);
393} 393}
394 394
395void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring) 395void radeon_ring_undo(struct radeon_ring *ring)
396{ 396{
397 ring->wptr = ring->wptr_old; 397 ring->wptr = ring->wptr_old;
398 mutex_unlock(&ring->mutex); 398}
399
400void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring)
401{
402 radeon_ring_undo(ring);
403 mutex_unlock(&rdev->ring_lock);
399} 404}
400 405
401void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring) 406void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring)
402{ 407{
403 int r; 408 int r;
404 409
405 mutex_lock(&ring->mutex); 410 mutex_lock(&rdev->ring_lock);
406 radeon_ring_free_size(rdev, ring); 411 radeon_ring_free_size(rdev, ring);
407 if (ring->rptr == ring->wptr) { 412 if (ring->rptr == ring->wptr) {
408 r = radeon_ring_alloc(rdev, ring, 1); 413 r = radeon_ring_alloc(rdev, ring, 1);
@@ -411,7 +416,7 @@ void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *
411 radeon_ring_commit(rdev, ring); 416 radeon_ring_commit(rdev, ring);
412 } 417 }
413 } 418 }
414 mutex_unlock(&ring->mutex); 419 mutex_unlock(&rdev->ring_lock);
415} 420}
416 421
417void radeon_ring_lockup_update(struct radeon_ring *ring) 422void radeon_ring_lockup_update(struct radeon_ring *ring)
@@ -520,11 +525,12 @@ void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring)
520 int r; 525 int r;
521 struct radeon_bo *ring_obj; 526 struct radeon_bo *ring_obj;
522 527
523 mutex_lock(&ring->mutex); 528 mutex_lock(&rdev->ring_lock);
524 ring_obj = ring->ring_obj; 529 ring_obj = ring->ring_obj;
530 ring->ready = false;
525 ring->ring = NULL; 531 ring->ring = NULL;
526 ring->ring_obj = NULL; 532 ring->ring_obj = NULL;
527 mutex_unlock(&ring->mutex); 533 mutex_unlock(&rdev->ring_lock);
528 534
529 if (ring_obj) { 535 if (ring_obj) {
530 r = radeon_bo_reserve(ring_obj, false); 536 r = radeon_bo_reserve(ring_obj, false);
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c
index 930a08af900f..c5b3d8ecece9 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -39,7 +39,6 @@ static int radeon_semaphore_add_bo(struct radeon_device *rdev)
39 uint32_t *cpu_ptr; 39 uint32_t *cpu_ptr;
40 int r, i; 40 int r, i;
41 41
42
43 bo = kmalloc(sizeof(struct radeon_semaphore_bo), GFP_KERNEL); 42 bo = kmalloc(sizeof(struct radeon_semaphore_bo), GFP_KERNEL);
44 if (bo == NULL) { 43 if (bo == NULL) {
45 return -ENOMEM; 44 return -ENOMEM;
@@ -154,13 +153,17 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev,
154 bool sync_to[RADEON_NUM_RINGS], 153 bool sync_to[RADEON_NUM_RINGS],
155 int dst_ring) 154 int dst_ring)
156{ 155{
157 int i, r; 156 int i = 0, r;
158 157
159 for (i = 0; i < RADEON_NUM_RINGS; ++i) { 158 mutex_lock(&rdev->ring_lock);
160 unsigned num_ops = i == dst_ring ? RADEON_NUM_RINGS : 1; 159 r = radeon_ring_alloc(rdev, &rdev->ring[dst_ring], RADEON_NUM_RINGS * 8);
160 if (r) {
161 goto error;
162 }
161 163
162 /* don't lock unused rings */ 164 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
163 if (!sync_to[i] && i != dst_ring) 165 /* no need to sync to our own or unused rings */
166 if (!sync_to[i] || i == dst_ring)
164 continue; 167 continue;
165 168
166 /* prevent GPU deadlocks */ 169 /* prevent GPU deadlocks */
@@ -170,38 +173,31 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev,
170 goto error; 173 goto error;
171 } 174 }
172 175
173 r = radeon_ring_lock(rdev, &rdev->ring[i], num_ops * 8); 176 r = radeon_ring_alloc(rdev, &rdev->ring[i], 8);
174 if (r) 177 if (r) {
175 goto error; 178 goto error;
176 } 179 }
177
178 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
179 /* no need to sync to our own or unused rings */
180 if (!sync_to[i] || i == dst_ring)
181 continue;
182 180
183 radeon_semaphore_emit_signal(rdev, i, semaphore); 181 radeon_semaphore_emit_signal(rdev, i, semaphore);
184 radeon_semaphore_emit_wait(rdev, dst_ring, semaphore); 182 radeon_semaphore_emit_wait(rdev, dst_ring, semaphore);
185 }
186 183
187 for (i = 0; i < RADEON_NUM_RINGS; ++i) { 184 radeon_ring_commit(rdev, &rdev->ring[i]);
188
189 /* don't unlock unused rings */
190 if (!sync_to[i] && i != dst_ring)
191 continue;
192
193 radeon_ring_unlock_commit(rdev, &rdev->ring[i]);
194 } 185 }
195 186
187 radeon_ring_commit(rdev, &rdev->ring[dst_ring]);
188 mutex_unlock(&rdev->ring_lock);
189
196 return 0; 190 return 0;
197 191
198error: 192error:
199 /* unlock all locks taken so far */ 193 /* unlock all locks taken so far */
200 for (--i; i >= 0; --i) { 194 for (--i; i >= 0; --i) {
201 if (sync_to[i] || i == dst_ring) { 195 if (sync_to[i] || i == dst_ring) {
202 radeon_ring_unlock_undo(rdev, &rdev->ring[i]); 196 radeon_ring_undo(&rdev->ring[i]);
203 } 197 }
204 } 198 }
199 radeon_ring_undo(&rdev->ring[dst_ring]);
200 mutex_unlock(&rdev->ring_lock);
205 return r; 201 return r;
206} 202}
207 203