diff options
author | Christian König <deathsimple@vodafone.de> | 2012-05-09 09:34:45 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-05-09 12:22:14 -0400 |
commit | d6999bc7b5f4b4554ebba5b48377903fa20198db (patch) | |
tree | 6dc61cf64362c4682d2bed9d591d8677376af795 /drivers/gpu/drm/radeon | |
parent | 133f4cb3365ef8e57c4837ffbe15de74684f6e19 (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.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ring.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_semaphore.c | 42 |
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 | |||
815 | int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); | 814 | int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); |
816 | void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *cp); | 815 | void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *cp); |
817 | void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *cp); | 816 | void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *cp); |
817 | void radeon_ring_undo(struct radeon_ring *ring); | ||
818 | void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp); | 818 | void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp); |
819 | int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); | 819 | int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); |
820 | void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring); | 820 | void 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) | |||
389 | void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring) | 389 | void 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 | ||
395 | void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring) | 395 | void 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 | |||
400 | void 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 | ||
401 | void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring) | 406 | void 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 | ||
417 | void radeon_ring_lockup_update(struct radeon_ring *ring) | 422 | void 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 | ||
198 | error: | 192 | error: |
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 | ||