Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon: split semaphore and sync object handling v2

Previously we just allocated space for four hardware semaphores
in each software semaphore object. Make software semaphore objects
represent only one hardware semaphore address again by splitting
the sync code into it's own object.

v2: fix typo in comment

Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Christian König and committed by
Alex Deucher
975700d2 e0602c35

+303 -260
+2 -1
drivers/gpu/drm/radeon/Makefile
··· 80 80 r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ 81 81 rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ 82 82 trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ 83 - ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o 83 + ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o \ 84 + radeon_sync.o 84 85 85 86 # add async DMA block 86 87 radeon-y += \
+7 -11
drivers/gpu/drm/radeon/cik.c
··· 3994 3994 unsigned num_gpu_pages, 3995 3995 struct reservation_object *resv) 3996 3996 { 3997 - struct radeon_semaphore *sem = NULL; 3998 3997 struct radeon_fence *fence; 3998 + struct radeon_sync sync; 3999 3999 int ring_index = rdev->asic->copy.blit_ring_index; 4000 4000 struct radeon_ring *ring = &rdev->ring[ring_index]; 4001 4001 u32 size_in_bytes, cur_size_in_bytes, control; 4002 4002 int i, num_loops; 4003 4003 int r = 0; 4004 4004 4005 - r = radeon_semaphore_create(rdev, &sem); 4006 - if (r) { 4007 - DRM_ERROR("radeon: moving bo (%d).\n", r); 4008 - return ERR_PTR(r); 4009 - } 4005 + radeon_sync_create(&sync); 4010 4006 4011 4007 size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); 4012 4008 num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); 4013 4009 r = radeon_ring_lock(rdev, ring, num_loops * 7 + 18); 4014 4010 if (r) { 4015 4011 DRM_ERROR("radeon: moving bo (%d).\n", r); 4016 - radeon_semaphore_free(rdev, &sem, NULL); 4012 + radeon_sync_free(rdev, &sync, NULL); 4017 4013 return ERR_PTR(r); 4018 4014 } 4019 4015 4020 - radeon_semaphore_sync_resv(rdev, sem, resv, false); 4021 - radeon_semaphore_sync_rings(rdev, sem, ring->idx); 4016 + radeon_sync_resv(rdev, &sync, resv, false); 4017 + radeon_sync_rings(rdev, &sync, ring->idx); 4022 4018 4023 4019 for (i = 0; i < num_loops; i++) { 4024 4020 cur_size_in_bytes = size_in_bytes; ··· 4038 4042 r = radeon_fence_emit(rdev, &fence, ring->idx); 4039 4043 if (r) { 4040 4044 radeon_ring_unlock_undo(rdev, ring); 4041 - radeon_semaphore_free(rdev, &sem, NULL); 4045 + radeon_sync_free(rdev, &sync, NULL); 4042 4046 return ERR_PTR(r); 4043 4047 } 4044 4048 4045 4049 radeon_ring_unlock_commit(rdev, ring, false); 4046 - radeon_semaphore_free(rdev, &sem, fence); 4050 + radeon_sync_free(rdev, &sync, fence); 4047 4051 4048 4052 return fence; 4049 4053 }
+7 -11
drivers/gpu/drm/radeon/cik_sdma.c
··· 541 541 unsigned num_gpu_pages, 542 542 struct reservation_object *resv) 543 543 { 544 - struct radeon_semaphore *sem = NULL; 545 544 struct radeon_fence *fence; 545 + struct radeon_sync sync; 546 546 int ring_index = rdev->asic->copy.dma_ring_index; 547 547 struct radeon_ring *ring = &rdev->ring[ring_index]; 548 548 u32 size_in_bytes, cur_size_in_bytes; 549 549 int i, num_loops; 550 550 int r = 0; 551 551 552 - r = radeon_semaphore_create(rdev, &sem); 553 - if (r) { 554 - DRM_ERROR("radeon: moving bo (%d).\n", r); 555 - return ERR_PTR(r); 556 - } 552 + radeon_sync_create(&sync); 557 553 558 554 size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); 559 555 num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); 560 556 r = radeon_ring_lock(rdev, ring, num_loops * 7 + 14); 561 557 if (r) { 562 558 DRM_ERROR("radeon: moving bo (%d).\n", r); 563 - radeon_semaphore_free(rdev, &sem, NULL); 559 + radeon_sync_free(rdev, &sync, NULL); 564 560 return ERR_PTR(r); 565 561 } 566 562 567 - radeon_semaphore_sync_resv(rdev, sem, resv, false); 568 - radeon_semaphore_sync_rings(rdev, sem, ring->idx); 563 + radeon_sync_resv(rdev, &sync, resv, false); 564 + radeon_sync_rings(rdev, &sync, ring->idx); 569 565 570 566 for (i = 0; i < num_loops; i++) { 571 567 cur_size_in_bytes = size_in_bytes; ··· 582 586 r = radeon_fence_emit(rdev, &fence, ring->idx); 583 587 if (r) { 584 588 radeon_ring_unlock_undo(rdev, ring); 585 - radeon_semaphore_free(rdev, &sem, NULL); 589 + radeon_sync_free(rdev, &sync, NULL); 586 590 return ERR_PTR(r); 587 591 } 588 592 589 593 radeon_ring_unlock_commit(rdev, ring, false); 590 - radeon_semaphore_free(rdev, &sem, fence); 594 + radeon_sync_free(rdev, &sync, fence); 591 595 592 596 return fence; 593 597 }
+7 -11
drivers/gpu/drm/radeon/evergreen_dma.c
··· 110 110 unsigned num_gpu_pages, 111 111 struct reservation_object *resv) 112 112 { 113 - struct radeon_semaphore *sem = NULL; 114 113 struct radeon_fence *fence; 114 + struct radeon_sync sync; 115 115 int ring_index = rdev->asic->copy.dma_ring_index; 116 116 struct radeon_ring *ring = &rdev->ring[ring_index]; 117 117 u32 size_in_dw, cur_size_in_dw; 118 118 int i, num_loops; 119 119 int r = 0; 120 120 121 - r = radeon_semaphore_create(rdev, &sem); 122 - if (r) { 123 - DRM_ERROR("radeon: moving bo (%d).\n", r); 124 - return ERR_PTR(r); 125 - } 121 + radeon_sync_create(&sync); 126 122 127 123 size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; 128 124 num_loops = DIV_ROUND_UP(size_in_dw, 0xfffff); 129 125 r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11); 130 126 if (r) { 131 127 DRM_ERROR("radeon: moving bo (%d).\n", r); 132 - radeon_semaphore_free(rdev, &sem, NULL); 128 + radeon_sync_free(rdev, &sync, NULL); 133 129 return ERR_PTR(r); 134 130 } 135 131 136 - radeon_semaphore_sync_resv(rdev, sem, resv, false); 137 - radeon_semaphore_sync_rings(rdev, sem, ring->idx); 132 + radeon_sync_resv(rdev, &sync, resv, false); 133 + radeon_sync_rings(rdev, &sync, ring->idx); 138 134 139 135 for (i = 0; i < num_loops; i++) { 140 136 cur_size_in_dw = size_in_dw; ··· 149 153 r = radeon_fence_emit(rdev, &fence, ring->idx); 150 154 if (r) { 151 155 radeon_ring_unlock_undo(rdev, ring); 152 - radeon_semaphore_free(rdev, &sem, NULL); 156 + radeon_sync_free(rdev, &sync, NULL); 153 157 return ERR_PTR(r); 154 158 } 155 159 156 160 radeon_ring_unlock_commit(rdev, ring, false); 157 - radeon_semaphore_free(rdev, &sem, fence); 161 + radeon_sync_free(rdev, &sync, fence); 158 162 159 163 return fence; 160 164 }
+7 -11
drivers/gpu/drm/radeon/r600.c
··· 2889 2889 unsigned num_gpu_pages, 2890 2890 struct reservation_object *resv) 2891 2891 { 2892 - struct radeon_semaphore *sem = NULL; 2893 2892 struct radeon_fence *fence; 2893 + struct radeon_sync sync; 2894 2894 int ring_index = rdev->asic->copy.blit_ring_index; 2895 2895 struct radeon_ring *ring = &rdev->ring[ring_index]; 2896 2896 u32 size_in_bytes, cur_size_in_bytes, tmp; 2897 2897 int i, num_loops; 2898 2898 int r = 0; 2899 2899 2900 - r = radeon_semaphore_create(rdev, &sem); 2901 - if (r) { 2902 - DRM_ERROR("radeon: moving bo (%d).\n", r); 2903 - return ERR_PTR(r); 2904 - } 2900 + radeon_sync_create(&sync); 2905 2901 2906 2902 size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); 2907 2903 num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); 2908 2904 r = radeon_ring_lock(rdev, ring, num_loops * 6 + 24); 2909 2905 if (r) { 2910 2906 DRM_ERROR("radeon: moving bo (%d).\n", r); 2911 - radeon_semaphore_free(rdev, &sem, NULL); 2907 + radeon_sync_free(rdev, &sync, NULL); 2912 2908 return ERR_PTR(r); 2913 2909 } 2914 2910 2915 - radeon_semaphore_sync_resv(rdev, sem, resv, false); 2916 - radeon_semaphore_sync_rings(rdev, sem, ring->idx); 2911 + radeon_sync_resv(rdev, &sync, resv, false); 2912 + radeon_sync_rings(rdev, &sync, ring->idx); 2917 2913 2918 2914 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 2919 2915 radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); ··· 2938 2942 r = radeon_fence_emit(rdev, &fence, ring->idx); 2939 2943 if (r) { 2940 2944 radeon_ring_unlock_undo(rdev, ring); 2941 - radeon_semaphore_free(rdev, &sem, NULL); 2945 + radeon_sync_free(rdev, &sync, NULL); 2942 2946 return ERR_PTR(r); 2943 2947 } 2944 2948 2945 2949 radeon_ring_unlock_commit(rdev, ring, false); 2946 - radeon_semaphore_free(rdev, &sem, fence); 2950 + radeon_sync_free(rdev, &sync, fence); 2947 2951 2948 2952 return fence; 2949 2953 }
+7 -11
drivers/gpu/drm/radeon/r600_dma.c
··· 441 441 unsigned num_gpu_pages, 442 442 struct reservation_object *resv) 443 443 { 444 - struct radeon_semaphore *sem = NULL; 445 444 struct radeon_fence *fence; 445 + struct radeon_sync sync; 446 446 int ring_index = rdev->asic->copy.dma_ring_index; 447 447 struct radeon_ring *ring = &rdev->ring[ring_index]; 448 448 u32 size_in_dw, cur_size_in_dw; 449 449 int i, num_loops; 450 450 int r = 0; 451 451 452 - r = radeon_semaphore_create(rdev, &sem); 453 - if (r) { 454 - DRM_ERROR("radeon: moving bo (%d).\n", r); 455 - return ERR_PTR(r); 456 - } 452 + radeon_sync_create(&sync); 457 453 458 454 size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; 459 455 num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFE); 460 456 r = radeon_ring_lock(rdev, ring, num_loops * 4 + 8); 461 457 if (r) { 462 458 DRM_ERROR("radeon: moving bo (%d).\n", r); 463 - radeon_semaphore_free(rdev, &sem, NULL); 459 + radeon_sync_free(rdev, &sync, NULL); 464 460 return ERR_PTR(r); 465 461 } 466 462 467 - radeon_semaphore_sync_resv(rdev, sem, resv, false); 468 - radeon_semaphore_sync_rings(rdev, sem, ring->idx); 463 + radeon_sync_resv(rdev, &sync, resv, false); 464 + radeon_sync_rings(rdev, &sync, ring->idx); 469 465 470 466 for (i = 0; i < num_loops; i++) { 471 467 cur_size_in_dw = size_in_dw; ··· 480 484 r = radeon_fence_emit(rdev, &fence, ring->idx); 481 485 if (r) { 482 486 radeon_ring_unlock_undo(rdev, ring); 483 - radeon_semaphore_free(rdev, &sem, NULL); 487 + radeon_sync_free(rdev, &sync, NULL); 484 488 return ERR_PTR(r); 485 489 } 486 490 487 491 radeon_ring_unlock_commit(rdev, ring, false); 488 - radeon_semaphore_free(rdev, &sem, fence); 492 + radeon_sync_free(rdev, &sync, fence); 489 493 490 494 return fence; 491 495 }
+25 -17
drivers/gpu/drm/radeon/radeon.h
··· 150 150 /* number of hw syncs before falling back on blocking */ 151 151 #define RADEON_NUM_SYNCS 4 152 152 153 - /* number of hw syncs before falling back on blocking */ 154 - #define RADEON_NUM_SYNCS 4 155 - 156 153 /* hardcode those limit for now */ 157 154 #define RADEON_VA_IB_OFFSET (1 << 20) 158 155 #define RADEON_VA_RESERVED_SIZE (8 << 20) ··· 573 576 * Semaphores. 574 577 */ 575 578 struct radeon_semaphore { 576 - struct radeon_sa_bo *sa_bo; 577 - signed waiters; 578 - uint64_t gpu_addr; 579 - struct radeon_fence *sync_to[RADEON_NUM_RINGS]; 579 + struct radeon_sa_bo *sa_bo; 580 + signed waiters; 581 + uint64_t gpu_addr; 580 582 }; 581 583 582 584 int radeon_semaphore_create(struct radeon_device *rdev, ··· 584 588 struct radeon_semaphore *semaphore); 585 589 bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, 586 590 struct radeon_semaphore *semaphore); 587 - void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, 588 - struct radeon_fence *fence); 589 - int radeon_semaphore_sync_resv(struct radeon_device *rdev, 590 - struct radeon_semaphore *semaphore, 591 - struct reservation_object *resv, 592 - bool shared); 593 - int radeon_semaphore_sync_rings(struct radeon_device *rdev, 594 - struct radeon_semaphore *semaphore, 595 - int waiting_ring); 596 591 void radeon_semaphore_free(struct radeon_device *rdev, 597 592 struct radeon_semaphore **semaphore, 598 593 struct radeon_fence *fence); 594 + 595 + /* 596 + * Synchronization 597 + */ 598 + struct radeon_sync { 599 + struct radeon_semaphore *semaphores[RADEON_NUM_SYNCS]; 600 + struct radeon_fence *sync_to[RADEON_NUM_RINGS]; 601 + }; 602 + 603 + void radeon_sync_create(struct radeon_sync *sync); 604 + void radeon_sync_fence(struct radeon_sync *sync, 605 + struct radeon_fence *fence); 606 + int radeon_sync_resv(struct radeon_device *rdev, 607 + struct radeon_sync *sync, 608 + struct reservation_object *resv, 609 + bool shared); 610 + int radeon_sync_rings(struct radeon_device *rdev, 611 + struct radeon_sync *sync, 612 + int waiting_ring); 613 + void radeon_sync_free(struct radeon_device *rdev, struct radeon_sync *sync, 614 + struct radeon_fence *fence); 599 615 600 616 /* 601 617 * GART structures, functions & helpers ··· 826 818 struct radeon_fence *fence; 827 819 struct radeon_vm *vm; 828 820 bool is_const_ib; 829 - struct radeon_semaphore *semaphore; 821 + struct radeon_sync sync; 830 822 }; 831 823 832 824 struct radeon_ring {
+3 -5
drivers/gpu/drm/radeon/radeon_cs.c
··· 260 260 continue; 261 261 262 262 resv = p->relocs[i].robj->tbo.resv; 263 - r = radeon_semaphore_sync_resv(p->rdev, p->ib.semaphore, resv, 264 - p->relocs[i].tv.shared); 263 + r = radeon_sync_resv(p->rdev, &p->ib.sync, resv, 264 + p->relocs[i].tv.shared); 265 265 266 266 if (r) 267 267 break; ··· 285 285 INIT_LIST_HEAD(&p->validated); 286 286 p->idx = 0; 287 287 p->ib.sa_bo = NULL; 288 - p->ib.semaphore = NULL; 289 288 p->const_ib.sa_bo = NULL; 290 - p->const_ib.semaphore = NULL; 291 289 p->chunk_ib_idx = -1; 292 290 p->chunk_relocs_idx = -1; 293 291 p->chunk_flags_idx = -1; ··· 580 582 DRM_ERROR("Failed to sync rings: %i\n", r); 581 583 goto out; 582 584 } 583 - radeon_semaphore_sync_fence(parser->ib.semaphore, vm->fence); 585 + radeon_sync_fence(&parser->ib.sync, vm->fence); 584 586 585 587 if ((rdev->family >= CHIP_TAHITI) && 586 588 (parser->chunk_const_ib_idx != -1)) {
+5 -8
drivers/gpu/drm/radeon/radeon_ib.c
··· 64 64 return r; 65 65 } 66 66 67 - r = radeon_semaphore_create(rdev, &ib->semaphore); 68 - if (r) { 69 - return r; 70 - } 67 + radeon_sync_create(&ib->sync); 71 68 72 69 ib->ring = ring; 73 70 ib->fence = NULL; ··· 93 96 */ 94 97 void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) 95 98 { 96 - radeon_semaphore_free(rdev, &ib->semaphore, ib->fence); 99 + radeon_sync_free(rdev, &ib->sync, ib->fence); 97 100 radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence); 98 101 radeon_fence_unref(&ib->fence); 99 102 } ··· 142 145 if (ib->vm) { 143 146 struct radeon_fence *vm_id_fence; 144 147 vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring); 145 - radeon_semaphore_sync_fence(ib->semaphore, vm_id_fence); 148 + radeon_sync_fence(&ib->sync, vm_id_fence); 146 149 } 147 150 148 151 /* sync with other rings */ 149 - r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring); 152 + r = radeon_sync_rings(rdev, &ib->sync, ib->ring); 150 153 if (r) { 151 154 dev_err(rdev->dev, "failed to sync rings (%d)\n", r); 152 155 radeon_ring_unlock_undo(rdev, ring); ··· 158 161 159 162 if (const_ib) { 160 163 radeon_ring_ib_execute(rdev, const_ib->ring, const_ib); 161 - radeon_semaphore_free(rdev, &const_ib->semaphore, NULL); 164 + radeon_sync_free(rdev, &const_ib->sync, NULL); 162 165 } 163 166 radeon_ring_ib_execute(rdev, ib->ring, ib); 164 167 r = radeon_fence_emit(rdev, &ib->fence, ib->ring);
+4 -150
drivers/gpu/drm/radeon/radeon_semaphore.c
··· 34 34 int radeon_semaphore_create(struct radeon_device *rdev, 35 35 struct radeon_semaphore **semaphore) 36 36 { 37 - uint64_t *cpu_addr; 38 - int i, r; 37 + int r; 39 38 40 39 *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); 41 40 if (*semaphore == NULL) { 42 41 return -ENOMEM; 43 42 } 44 - r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &(*semaphore)->sa_bo, 45 - 8 * RADEON_NUM_SYNCS, 8); 43 + r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, 44 + &(*semaphore)->sa_bo, 8, 8); 46 45 if (r) { 47 46 kfree(*semaphore); 48 47 *semaphore = NULL; ··· 50 51 (*semaphore)->waiters = 0; 51 52 (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo); 52 53 53 - cpu_addr = radeon_sa_bo_cpu_addr((*semaphore)->sa_bo); 54 - for (i = 0; i < RADEON_NUM_SYNCS; ++i) 55 - cpu_addr[i] = 0; 56 - 57 - for (i = 0; i < RADEON_NUM_RINGS; ++i) 58 - (*semaphore)->sync_to[i] = NULL; 54 + *((uint64_t *)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0; 59 55 60 56 return 0; 61 57 } ··· 87 93 return true; 88 94 } 89 95 return false; 90 - } 91 - 92 - /** 93 - * radeon_semaphore_sync_fence - use the semaphore to sync to a fence 94 - * 95 - * @semaphore: semaphore object to add fence to 96 - * @fence: fence to sync to 97 - * 98 - * Sync to the fence using this semaphore object 99 - */ 100 - void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, 101 - struct radeon_fence *fence) 102 - { 103 - struct radeon_fence *other; 104 - 105 - if (!fence) 106 - return; 107 - 108 - other = semaphore->sync_to[fence->ring]; 109 - semaphore->sync_to[fence->ring] = radeon_fence_later(fence, other); 110 - } 111 - 112 - /** 113 - * radeon_semaphore_sync_to - use the semaphore to sync to a reservation object 114 - * 115 - * @sema: semaphore object to add fence from reservation object to 116 - * @resv: reservation object with embedded fence 117 - * @shared: true if we should onyl sync to the exclusive fence 118 - * 119 - * Sync to the fence using this semaphore object 120 - */ 121 - int radeon_semaphore_sync_resv(struct radeon_device *rdev, 122 - struct radeon_semaphore *sema, 123 - struct reservation_object *resv, 124 - bool shared) 125 - { 126 - struct reservation_object_list *flist; 127 - struct fence *f; 128 - struct radeon_fence *fence; 129 - unsigned i; 130 - int r = 0; 131 - 132 - /* always sync to the exclusive fence */ 133 - f = reservation_object_get_excl(resv); 134 - fence = f ? to_radeon_fence(f) : NULL; 135 - if (fence && fence->rdev == rdev) 136 - radeon_semaphore_sync_fence(sema, fence); 137 - else if (f) 138 - r = fence_wait(f, true); 139 - 140 - flist = reservation_object_get_list(resv); 141 - if (shared || !flist || r) 142 - return r; 143 - 144 - for (i = 0; i < flist->shared_count; ++i) { 145 - f = rcu_dereference_protected(flist->shared[i], 146 - reservation_object_held(resv)); 147 - fence = to_radeon_fence(f); 148 - if (fence && fence->rdev == rdev) 149 - radeon_semaphore_sync_fence(sema, fence); 150 - else 151 - r = fence_wait(f, true); 152 - 153 - if (r) 154 - break; 155 - } 156 - return r; 157 - } 158 - 159 - /** 160 - * radeon_semaphore_sync_rings - sync ring to all registered fences 161 - * 162 - * @rdev: radeon_device pointer 163 - * @semaphore: semaphore object to use for sync 164 - * @ring: ring that needs sync 165 - * 166 - * Ensure that all registered fences are signaled before letting 167 - * the ring continue. The caller must hold the ring lock. 168 - */ 169 - int radeon_semaphore_sync_rings(struct radeon_device *rdev, 170 - struct radeon_semaphore *semaphore, 171 - int ring) 172 - { 173 - unsigned count = 0; 174 - int i, r; 175 - 176 - for (i = 0; i < RADEON_NUM_RINGS; ++i) { 177 - struct radeon_fence *fence = semaphore->sync_to[i]; 178 - 179 - /* check if we really need to sync */ 180 - if (!radeon_fence_need_sync(fence, ring)) 181 - continue; 182 - 183 - /* prevent GPU deadlocks */ 184 - if (!rdev->ring[i].ready) { 185 - dev_err(rdev->dev, "Syncing to a disabled ring!"); 186 - return -EINVAL; 187 - } 188 - 189 - if (++count > RADEON_NUM_SYNCS) { 190 - /* not enough room, wait manually */ 191 - r = radeon_fence_wait(fence, false); 192 - if (r) 193 - return r; 194 - continue; 195 - } 196 - 197 - /* allocate enough space for sync command */ 198 - r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); 199 - if (r) { 200 - return r; 201 - } 202 - 203 - /* emit the signal semaphore */ 204 - if (!radeon_semaphore_emit_signal(rdev, i, semaphore)) { 205 - /* signaling wasn't successful wait manually */ 206 - radeon_ring_undo(&rdev->ring[i]); 207 - r = radeon_fence_wait(fence, false); 208 - if (r) 209 - return r; 210 - continue; 211 - } 212 - 213 - /* we assume caller has already allocated space on waiters ring */ 214 - if (!radeon_semaphore_emit_wait(rdev, ring, semaphore)) { 215 - /* waiting wasn't successful wait manually */ 216 - radeon_ring_undo(&rdev->ring[i]); 217 - r = radeon_fence_wait(fence, false); 218 - if (r) 219 - return r; 220 - continue; 221 - } 222 - 223 - radeon_ring_commit(rdev, &rdev->ring[i], false); 224 - radeon_fence_note_sync(fence, ring); 225 - 226 - semaphore->gpu_addr += 8; 227 - } 228 - 229 - return 0; 230 96 } 231 97 232 98 void radeon_semaphore_free(struct radeon_device *rdev,
+213
drivers/gpu/drm/radeon/radeon_sync.c
··· 1 + /* 2 + * Copyright 2014 Advanced Micro Devices, Inc. 3 + * All Rights Reserved. 4 + * 5 + * Permission is hereby granted, free of charge, to any person obtaining a 6 + * copy of this software and associated documentation files (the 7 + * "Software"), to deal in the Software without restriction, including 8 + * without limitation the rights to use, copy, modify, merge, publish, 9 + * distribute, sub license, and/or sell copies of the Software, and to 10 + * permit persons to whom the Software is furnished to do so, subject to 11 + * the following conditions: 12 + * 13 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 16 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 17 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 19 + * USE OR OTHER DEALINGS IN THE SOFTWARE. 20 + * 21 + * The above copyright notice and this permission notice (including the 22 + * next paragraph) shall be included in all copies or substantial portions 23 + * of the Software. 24 + * 25 + */ 26 + /* 27 + * Authors: 28 + * Christian König <christian.koenig@amd.com> 29 + */ 30 + 31 + #include <drm/drmP.h> 32 + #include "radeon.h" 33 + #include "radeon_trace.h" 34 + 35 + /** 36 + * radeon_sync_create - zero init sync object 37 + * 38 + * @sync: sync object to initialize 39 + * 40 + * Just clear the sync object for now. 41 + */ 42 + void radeon_sync_create(struct radeon_sync *sync) 43 + { 44 + unsigned i; 45 + 46 + for (i = 0; i < RADEON_NUM_SYNCS; ++i) 47 + sync->semaphores[i] = NULL; 48 + 49 + for (i = 0; i < RADEON_NUM_RINGS; ++i) 50 + sync->sync_to[i] = NULL; 51 + } 52 + 53 + /** 54 + * radeon_sync_fence - use the semaphore to sync to a fence 55 + * 56 + * @sync: sync object to add fence to 57 + * @fence: fence to sync to 58 + * 59 + * Sync to the fence using the semaphore objects 60 + */ 61 + void radeon_sync_fence(struct radeon_sync *sync, 62 + struct radeon_fence *fence) 63 + { 64 + struct radeon_fence *other; 65 + 66 + if (!fence) 67 + return; 68 + 69 + other = sync->sync_to[fence->ring]; 70 + sync->sync_to[fence->ring] = radeon_fence_later(fence, other); 71 + } 72 + 73 + /** 74 + * radeon_sync_resv - use the semaphores to sync to a reservation object 75 + * 76 + * @sync: sync object to add fences from reservation object to 77 + * @resv: reservation object with embedded fence 78 + * @shared: true if we should only sync to the exclusive fence 79 + * 80 + * Sync to the fence using the semaphore objects 81 + */ 82 + int radeon_sync_resv(struct radeon_device *rdev, 83 + struct radeon_sync *sync, 84 + struct reservation_object *resv, 85 + bool shared) 86 + { 87 + struct reservation_object_list *flist; 88 + struct fence *f; 89 + struct radeon_fence *fence; 90 + unsigned i; 91 + int r = 0; 92 + 93 + /* always sync to the exclusive fence */ 94 + f = reservation_object_get_excl(resv); 95 + fence = f ? to_radeon_fence(f) : NULL; 96 + if (fence && fence->rdev == rdev) 97 + radeon_sync_fence(sync, fence); 98 + else if (f) 99 + r = fence_wait(f, true); 100 + 101 + flist = reservation_object_get_list(resv); 102 + if (shared || !flist || r) 103 + return r; 104 + 105 + for (i = 0; i < flist->shared_count; ++i) { 106 + f = rcu_dereference_protected(flist->shared[i], 107 + reservation_object_held(resv)); 108 + fence = to_radeon_fence(f); 109 + if (fence && fence->rdev == rdev) 110 + radeon_sync_fence(sync, fence); 111 + else 112 + r = fence_wait(f, true); 113 + 114 + if (r) 115 + break; 116 + } 117 + return r; 118 + } 119 + 120 + /** 121 + * radeon_sync_rings - sync ring to all registered fences 122 + * 123 + * @rdev: radeon_device pointer 124 + * @sync: sync object to use 125 + * @ring: ring that needs sync 126 + * 127 + * Ensure that all registered fences are signaled before letting 128 + * the ring continue. The caller must hold the ring lock. 129 + */ 130 + int radeon_sync_rings(struct radeon_device *rdev, 131 + struct radeon_sync *sync, 132 + int ring) 133 + { 134 + unsigned count = 0; 135 + int i, r; 136 + 137 + for (i = 0; i < RADEON_NUM_RINGS; ++i) { 138 + struct radeon_fence *fence = sync->sync_to[i]; 139 + struct radeon_semaphore *semaphore; 140 + 141 + /* check if we really need to sync */ 142 + if (!radeon_fence_need_sync(fence, ring)) 143 + continue; 144 + 145 + /* prevent GPU deadlocks */ 146 + if (!rdev->ring[i].ready) { 147 + dev_err(rdev->dev, "Syncing to a disabled ring!"); 148 + return -EINVAL; 149 + } 150 + 151 + if (count >= RADEON_NUM_SYNCS) { 152 + /* not enough room, wait manually */ 153 + r = radeon_fence_wait(fence, false); 154 + if (r) 155 + return r; 156 + continue; 157 + } 158 + r = radeon_semaphore_create(rdev, &semaphore); 159 + if (r) 160 + return r; 161 + 162 + sync->semaphores[count++] = semaphore; 163 + 164 + /* allocate enough space for sync command */ 165 + r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); 166 + if (r) 167 + return r; 168 + 169 + /* emit the signal semaphore */ 170 + if (!radeon_semaphore_emit_signal(rdev, i, semaphore)) { 171 + /* signaling wasn't successful wait manually */ 172 + radeon_ring_undo(&rdev->ring[i]); 173 + r = radeon_fence_wait(fence, false); 174 + if (r) 175 + return r; 176 + continue; 177 + } 178 + 179 + /* we assume caller has already allocated space on waiters ring */ 180 + if (!radeon_semaphore_emit_wait(rdev, ring, semaphore)) { 181 + /* waiting wasn't successful wait manually */ 182 + radeon_ring_undo(&rdev->ring[i]); 183 + r = radeon_fence_wait(fence, false); 184 + if (r) 185 + return r; 186 + continue; 187 + } 188 + 189 + radeon_ring_commit(rdev, &rdev->ring[i], false); 190 + radeon_fence_note_sync(fence, ring); 191 + } 192 + 193 + return 0; 194 + } 195 + 196 + /** 197 + * radeon_sync_free - free the sync object 198 + * 199 + * @rdev: radeon_device pointer 200 + * @sync: sync object to use 201 + * @fence: fence to use for the free 202 + * 203 + * Free the sync object by freeing all semaphores in it. 204 + */ 205 + void radeon_sync_free(struct radeon_device *rdev, 206 + struct radeon_sync *sync, 207 + struct radeon_fence *fence) 208 + { 209 + unsigned i; 210 + 211 + for (i = 0; i < RADEON_NUM_SYNCS; ++i) 212 + radeon_semaphore_free(rdev, &sync->semaphores[i], fence); 213 + }
+2 -2
drivers/gpu/drm/radeon/radeon_vm.c
··· 700 700 if (ib.length_dw != 0) { 701 701 radeon_asic_vm_pad_ib(rdev, &ib); 702 702 703 - radeon_semaphore_sync_resv(rdev, ib.semaphore, pd->tbo.resv, false); 703 + radeon_sync_resv(rdev, &ib.sync, pd->tbo.resv, false); 704 704 WARN_ON(ib.length_dw > ndw); 705 705 r = radeon_ib_schedule(rdev, &ib, NULL, false); 706 706 if (r) { ··· 826 826 unsigned nptes; 827 827 uint64_t pte; 828 828 829 - radeon_semaphore_sync_resv(rdev, ib->semaphore, pt->tbo.resv, false); 829 + radeon_sync_resv(rdev, &ib->sync, pt->tbo.resv, false); 830 830 831 831 if ((addr & ~mask) == (end & ~mask)) 832 832 nptes = end - addr;
+7 -11
drivers/gpu/drm/radeon/rv770_dma.c
··· 44 44 unsigned num_gpu_pages, 45 45 struct reservation_object *resv) 46 46 { 47 - struct radeon_semaphore *sem = NULL; 48 47 struct radeon_fence *fence; 48 + struct radeon_sync sync; 49 49 int ring_index = rdev->asic->copy.dma_ring_index; 50 50 struct radeon_ring *ring = &rdev->ring[ring_index]; 51 51 u32 size_in_dw, cur_size_in_dw; 52 52 int i, num_loops; 53 53 int r = 0; 54 54 55 - r = radeon_semaphore_create(rdev, &sem); 56 - if (r) { 57 - DRM_ERROR("radeon: moving bo (%d).\n", r); 58 - return ERR_PTR(r); 59 - } 55 + radeon_sync_create(&sync); 60 56 61 57 size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; 62 58 num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFF); 63 59 r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8); 64 60 if (r) { 65 61 DRM_ERROR("radeon: moving bo (%d).\n", r); 66 - radeon_semaphore_free(rdev, &sem, NULL); 62 + radeon_sync_free(rdev, &sync, NULL); 67 63 return ERR_PTR(r); 68 64 } 69 65 70 - radeon_semaphore_sync_resv(rdev, sem, resv, false); 71 - radeon_semaphore_sync_rings(rdev, sem, ring->idx); 66 + radeon_sync_resv(rdev, &sync, resv, false); 67 + radeon_sync_rings(rdev, &sync, ring->idx); 72 68 73 69 for (i = 0; i < num_loops; i++) { 74 70 cur_size_in_dw = size_in_dw; ··· 83 87 r = radeon_fence_emit(rdev, &fence, ring->idx); 84 88 if (r) { 85 89 radeon_ring_unlock_undo(rdev, ring); 86 - radeon_semaphore_free(rdev, &sem, NULL); 90 + radeon_sync_free(rdev, &sync, NULL); 87 91 return ERR_PTR(r); 88 92 } 89 93 90 94 radeon_ring_unlock_commit(rdev, ring, false); 91 - radeon_semaphore_free(rdev, &sem, fence); 95 + radeon_sync_free(rdev, &sync, fence); 92 96 93 97 return fence; 94 98 }
+7 -11
drivers/gpu/drm/radeon/si_dma.c
··· 226 226 unsigned num_gpu_pages, 227 227 struct reservation_object *resv) 228 228 { 229 - struct radeon_semaphore *sem = NULL; 230 229 struct radeon_fence *fence; 230 + struct radeon_sync sync; 231 231 int ring_index = rdev->asic->copy.dma_ring_index; 232 232 struct radeon_ring *ring = &rdev->ring[ring_index]; 233 233 u32 size_in_bytes, cur_size_in_bytes; 234 234 int i, num_loops; 235 235 int r = 0; 236 236 237 - r = radeon_semaphore_create(rdev, &sem); 238 - if (r) { 239 - DRM_ERROR("radeon: moving bo (%d).\n", r); 240 - return ERR_PTR(r); 241 - } 237 + radeon_sync_create(&sync); 242 238 243 239 size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); 244 240 num_loops = DIV_ROUND_UP(size_in_bytes, 0xfffff); 245 241 r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11); 246 242 if (r) { 247 243 DRM_ERROR("radeon: moving bo (%d).\n", r); 248 - radeon_semaphore_free(rdev, &sem, NULL); 244 + radeon_sync_free(rdev, &sync, NULL); 249 245 return ERR_PTR(r); 250 246 } 251 247 252 - radeon_semaphore_sync_resv(rdev, sem, resv, false); 253 - radeon_semaphore_sync_rings(rdev, sem, ring->idx); 248 + radeon_sync_resv(rdev, &sync, resv, false); 249 + radeon_sync_rings(rdev, &sync, ring->idx); 254 250 255 251 for (i = 0; i < num_loops; i++) { 256 252 cur_size_in_bytes = size_in_bytes; ··· 265 269 r = radeon_fence_emit(rdev, &fence, ring->idx); 266 270 if (r) { 267 271 radeon_ring_unlock_undo(rdev, ring); 268 - radeon_semaphore_free(rdev, &sem, NULL); 272 + radeon_sync_free(rdev, &sync, NULL); 269 273 return ERR_PTR(r); 270 274 } 271 275 272 276 radeon_ring_unlock_commit(rdev, ring, false); 273 - radeon_semaphore_free(rdev, &sem, fence); 277 + radeon_sync_free(rdev, &sync, fence); 274 278 275 279 return fence; 276 280 }