diff options
23 files changed, 284 insertions, 211 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index a6e19c83143e..446e71ca36cb 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c | |||
| @@ -226,6 +226,7 @@ int qxl_release_list_add(struct qxl_release *release, struct qxl_bo *bo) | |||
| 226 | 226 | ||
| 227 | qxl_bo_ref(bo); | 227 | qxl_bo_ref(bo); |
| 228 | entry->tv.bo = &bo->tbo; | 228 | entry->tv.bo = &bo->tbo; |
| 229 | entry->tv.shared = false; | ||
| 229 | list_add_tail(&entry->tv.head, &release->bos); | 230 | list_add_tail(&entry->tv.head, &release->bos); |
| 230 | return 0; | 231 | return 0; |
| 231 | } | 232 | } |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 1f598ab3b9a7..0b5a230d8b96 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
| @@ -3959,18 +3959,19 @@ bool cik_semaphore_ring_emit(struct radeon_device *rdev, | |||
| 3959 | * @src_offset: src GPU address | 3959 | * @src_offset: src GPU address |
| 3960 | * @dst_offset: dst GPU address | 3960 | * @dst_offset: dst GPU address |
| 3961 | * @num_gpu_pages: number of GPU pages to xfer | 3961 | * @num_gpu_pages: number of GPU pages to xfer |
| 3962 | * @fence: radeon fence object | 3962 | * @resv: reservation object to sync to |
| 3963 | * | 3963 | * |
| 3964 | * Copy GPU paging using the CP DMA engine (CIK+). | 3964 | * Copy GPU paging using the CP DMA engine (CIK+). |
| 3965 | * Used by the radeon ttm implementation to move pages if | 3965 | * Used by the radeon ttm implementation to move pages if |
| 3966 | * registered as the asic copy callback. | 3966 | * registered as the asic copy callback. |
| 3967 | */ | 3967 | */ |
| 3968 | int cik_copy_cpdma(struct radeon_device *rdev, | 3968 | struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev, |
| 3969 | uint64_t src_offset, uint64_t dst_offset, | 3969 | uint64_t src_offset, uint64_t dst_offset, |
| 3970 | unsigned num_gpu_pages, | 3970 | unsigned num_gpu_pages, |
| 3971 | struct radeon_fence **fence) | 3971 | struct reservation_object *resv) |
| 3972 | { | 3972 | { |
| 3973 | struct radeon_semaphore *sem = NULL; | 3973 | struct radeon_semaphore *sem = NULL; |
| 3974 | struct radeon_fence *fence; | ||
| 3974 | int ring_index = rdev->asic->copy.blit_ring_index; | 3975 | int ring_index = rdev->asic->copy.blit_ring_index; |
| 3975 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 3976 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
| 3976 | u32 size_in_bytes, cur_size_in_bytes, control; | 3977 | u32 size_in_bytes, cur_size_in_bytes, control; |
| @@ -3980,7 +3981,7 @@ int cik_copy_cpdma(struct radeon_device *rdev, | |||
| 3980 | r = radeon_semaphore_create(rdev, &sem); | 3981 | r = radeon_semaphore_create(rdev, &sem); |
| 3981 | if (r) { | 3982 | if (r) { |
| 3982 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 3983 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 3983 | return r; | 3984 | return ERR_PTR(r); |
| 3984 | } | 3985 | } |
| 3985 | 3986 | ||
| 3986 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); | 3987 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); |
| @@ -3989,10 +3990,10 @@ int cik_copy_cpdma(struct radeon_device *rdev, | |||
| 3989 | if (r) { | 3990 | if (r) { |
| 3990 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 3991 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 3991 | radeon_semaphore_free(rdev, &sem, NULL); | 3992 | radeon_semaphore_free(rdev, &sem, NULL); |
| 3992 | return r; | 3993 | return ERR_PTR(r); |
| 3993 | } | 3994 | } |
| 3994 | 3995 | ||
| 3995 | radeon_semaphore_sync_to(sem, *fence); | 3996 | radeon_semaphore_sync_resv(sem, resv, false); |
| 3996 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 3997 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
| 3997 | 3998 | ||
| 3998 | for (i = 0; i < num_loops; i++) { | 3999 | for (i = 0; i < num_loops; i++) { |
| @@ -4014,17 +4015,17 @@ int cik_copy_cpdma(struct radeon_device *rdev, | |||
| 4014 | dst_offset += cur_size_in_bytes; | 4015 | dst_offset += cur_size_in_bytes; |
| 4015 | } | 4016 | } |
| 4016 | 4017 | ||
| 4017 | r = radeon_fence_emit(rdev, fence, ring->idx); | 4018 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
| 4018 | if (r) { | 4019 | if (r) { |
| 4019 | radeon_ring_unlock_undo(rdev, ring); | 4020 | radeon_ring_unlock_undo(rdev, ring); |
| 4020 | radeon_semaphore_free(rdev, &sem, NULL); | 4021 | radeon_semaphore_free(rdev, &sem, NULL); |
| 4021 | return r; | 4022 | return ERR_PTR(r); |
| 4022 | } | 4023 | } |
| 4023 | 4024 | ||
| 4024 | radeon_ring_unlock_commit(rdev, ring, false); | 4025 | radeon_ring_unlock_commit(rdev, ring, false); |
| 4025 | radeon_semaphore_free(rdev, &sem, *fence); | 4026 | radeon_semaphore_free(rdev, &sem, fence); |
| 4026 | 4027 | ||
| 4027 | return r; | 4028 | return fence; |
| 4028 | } | 4029 | } |
| 4029 | 4030 | ||
| 4030 | /* | 4031 | /* |
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index 192278bc993c..c01a6100c318 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c | |||
| @@ -537,18 +537,19 @@ void cik_sdma_fini(struct radeon_device *rdev) | |||
| 537 | * @src_offset: src GPU address | 537 | * @src_offset: src GPU address |
| 538 | * @dst_offset: dst GPU address | 538 | * @dst_offset: dst GPU address |
| 539 | * @num_gpu_pages: number of GPU pages to xfer | 539 | * @num_gpu_pages: number of GPU pages to xfer |
| 540 | * @fence: radeon fence object | 540 | * @resv: reservation object to sync to |
| 541 | * | 541 | * |
| 542 | * Copy GPU paging using the DMA engine (CIK). | 542 | * Copy GPU paging using the DMA engine (CIK). |
| 543 | * Used by the radeon ttm implementation to move pages if | 543 | * Used by the radeon ttm implementation to move pages if |
| 544 | * registered as the asic copy callback. | 544 | * registered as the asic copy callback. |
| 545 | */ | 545 | */ |
| 546 | int cik_copy_dma(struct radeon_device *rdev, | 546 | struct radeon_fence *cik_copy_dma(struct radeon_device *rdev, |
| 547 | uint64_t src_offset, uint64_t dst_offset, | 547 | uint64_t src_offset, uint64_t dst_offset, |
| 548 | unsigned num_gpu_pages, | 548 | unsigned num_gpu_pages, |
| 549 | struct radeon_fence **fence) | 549 | struct reservation_object *resv) |
| 550 | { | 550 | { |
| 551 | struct radeon_semaphore *sem = NULL; | 551 | struct radeon_semaphore *sem = NULL; |
| 552 | struct radeon_fence *fence; | ||
| 552 | int ring_index = rdev->asic->copy.dma_ring_index; | 553 | int ring_index = rdev->asic->copy.dma_ring_index; |
| 553 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 554 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
| 554 | u32 size_in_bytes, cur_size_in_bytes; | 555 | u32 size_in_bytes, cur_size_in_bytes; |
| @@ -558,7 +559,7 @@ int cik_copy_dma(struct radeon_device *rdev, | |||
| 558 | r = radeon_semaphore_create(rdev, &sem); | 559 | r = radeon_semaphore_create(rdev, &sem); |
| 559 | if (r) { | 560 | if (r) { |
| 560 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 561 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 561 | return r; | 562 | return ERR_PTR(r); |
| 562 | } | 563 | } |
| 563 | 564 | ||
| 564 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); | 565 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); |
| @@ -567,10 +568,10 @@ int cik_copy_dma(struct radeon_device *rdev, | |||
| 567 | if (r) { | 568 | if (r) { |
| 568 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 569 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 569 | radeon_semaphore_free(rdev, &sem, NULL); | 570 | radeon_semaphore_free(rdev, &sem, NULL); |
| 570 | return r; | 571 | return ERR_PTR(r); |
| 571 | } | 572 | } |
| 572 | 573 | ||
| 573 | radeon_semaphore_sync_to(sem, *fence); | 574 | radeon_semaphore_sync_resv(sem, resv, false); |
| 574 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 575 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
| 575 | 576 | ||
| 576 | for (i = 0; i < num_loops; i++) { | 577 | for (i = 0; i < num_loops; i++) { |
| @@ -589,17 +590,17 @@ int cik_copy_dma(struct radeon_device *rdev, | |||
| 589 | dst_offset += cur_size_in_bytes; | 590 | dst_offset += cur_size_in_bytes; |
| 590 | } | 591 | } |
| 591 | 592 | ||
| 592 | r = radeon_fence_emit(rdev, fence, ring->idx); | 593 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
| 593 | if (r) { | 594 | if (r) { |
| 594 | radeon_ring_unlock_undo(rdev, ring); | 595 | radeon_ring_unlock_undo(rdev, ring); |
| 595 | radeon_semaphore_free(rdev, &sem, NULL); | 596 | radeon_semaphore_free(rdev, &sem, NULL); |
| 596 | return r; | 597 | return ERR_PTR(r); |
| 597 | } | 598 | } |
| 598 | 599 | ||
| 599 | radeon_ring_unlock_commit(rdev, ring, false); | 600 | radeon_ring_unlock_commit(rdev, ring, false); |
| 600 | radeon_semaphore_free(rdev, &sem, *fence); | 601 | radeon_semaphore_free(rdev, &sem, fence); |
| 601 | 602 | ||
| 602 | return r; | 603 | return fence; |
| 603 | } | 604 | } |
| 604 | 605 | ||
| 605 | /** | 606 | /** |
diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c index afaba388c36d..946f37d0b469 100644 --- a/drivers/gpu/drm/radeon/evergreen_dma.c +++ b/drivers/gpu/drm/radeon/evergreen_dma.c | |||
| @@ -104,12 +104,14 @@ void evergreen_dma_ring_ib_execute(struct radeon_device *rdev, | |||
| 104 | * Used by the radeon ttm implementation to move pages if | 104 | * Used by the radeon ttm implementation to move pages if |
| 105 | * registered as the asic copy callback. | 105 | * registered as the asic copy callback. |
| 106 | */ | 106 | */ |
| 107 | int evergreen_copy_dma(struct radeon_device *rdev, | 107 | struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev, |
| 108 | uint64_t src_offset, uint64_t dst_offset, | 108 | uint64_t src_offset, |
| 109 | unsigned num_gpu_pages, | 109 | uint64_t dst_offset, |
| 110 | struct radeon_fence **fence) | 110 | unsigned num_gpu_pages, |
| 111 | struct reservation_object *resv) | ||
| 111 | { | 112 | { |
| 112 | struct radeon_semaphore *sem = NULL; | 113 | struct radeon_semaphore *sem = NULL; |
| 114 | struct radeon_fence *fence; | ||
| 113 | int ring_index = rdev->asic->copy.dma_ring_index; | 115 | int ring_index = rdev->asic->copy.dma_ring_index; |
| 114 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 116 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
| 115 | u32 size_in_dw, cur_size_in_dw; | 117 | u32 size_in_dw, cur_size_in_dw; |
| @@ -119,7 +121,7 @@ int evergreen_copy_dma(struct radeon_device *rdev, | |||
| 119 | r = radeon_semaphore_create(rdev, &sem); | 121 | r = radeon_semaphore_create(rdev, &sem); |
| 120 | if (r) { | 122 | if (r) { |
| 121 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 123 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 122 | return r; | 124 | return ERR_PTR(r); |
| 123 | } | 125 | } |
| 124 | 126 | ||
| 125 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; | 127 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; |
| @@ -128,10 +130,10 @@ int evergreen_copy_dma(struct radeon_device *rdev, | |||
| 128 | if (r) { | 130 | if (r) { |
| 129 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 131 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 130 | radeon_semaphore_free(rdev, &sem, NULL); | 132 | radeon_semaphore_free(rdev, &sem, NULL); |
| 131 | return r; | 133 | return ERR_PTR(r); |
| 132 | } | 134 | } |
| 133 | 135 | ||
| 134 | radeon_semaphore_sync_to(sem, *fence); | 136 | radeon_semaphore_sync_resv(sem, resv, false); |
| 135 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 137 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
| 136 | 138 | ||
| 137 | for (i = 0; i < num_loops; i++) { | 139 | for (i = 0; i < num_loops; i++) { |
| @@ -148,17 +150,17 @@ int evergreen_copy_dma(struct radeon_device *rdev, | |||
| 148 | dst_offset += cur_size_in_dw * 4; | 150 | dst_offset += cur_size_in_dw * 4; |
| 149 | } | 151 | } |
| 150 | 152 | ||
| 151 | r = radeon_fence_emit(rdev, fence, ring->idx); | 153 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
| 152 | if (r) { | 154 | if (r) { |
| 153 | radeon_ring_unlock_undo(rdev, ring); | 155 | radeon_ring_unlock_undo(rdev, ring); |
| 154 | radeon_semaphore_free(rdev, &sem, NULL); | 156 | radeon_semaphore_free(rdev, &sem, NULL); |
| 155 | return r; | 157 | return ERR_PTR(r); |
| 156 | } | 158 | } |
| 157 | 159 | ||
| 158 | radeon_ring_unlock_commit(rdev, ring, false); | 160 | radeon_ring_unlock_commit(rdev, ring, false); |
| 159 | radeon_semaphore_free(rdev, &sem, *fence); | 161 | radeon_semaphore_free(rdev, &sem, fence); |
| 160 | 162 | ||
| 161 | return r; | 163 | return fence; |
| 162 | } | 164 | } |
| 163 | 165 | ||
| 164 | /** | 166 | /** |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 4c5ec44ff328..c6b486f888d5 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -855,13 +855,14 @@ bool r100_semaphore_ring_emit(struct radeon_device *rdev, | |||
| 855 | return false; | 855 | return false; |
| 856 | } | 856 | } |
| 857 | 857 | ||
| 858 | int r100_copy_blit(struct radeon_device *rdev, | 858 | struct radeon_fence *r100_copy_blit(struct radeon_device *rdev, |
| 859 | uint64_t src_offset, | 859 | uint64_t src_offset, |
| 860 | uint64_t dst_offset, | 860 | uint64_t dst_offset, |
| 861 | unsigned num_gpu_pages, | 861 | unsigned num_gpu_pages, |
| 862 | struct radeon_fence **fence) | 862 | struct reservation_object *resv) |
| 863 | { | 863 | { |
| 864 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 864 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
| 865 | struct radeon_fence *fence; | ||
| 865 | uint32_t cur_pages; | 866 | uint32_t cur_pages; |
| 866 | uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE; | 867 | uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE; |
| 867 | uint32_t pitch; | 868 | uint32_t pitch; |
| @@ -882,7 +883,7 @@ int r100_copy_blit(struct radeon_device *rdev, | |||
| 882 | r = radeon_ring_lock(rdev, ring, ndw); | 883 | r = radeon_ring_lock(rdev, ring, ndw); |
| 883 | if (r) { | 884 | if (r) { |
| 884 | DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw); | 885 | DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw); |
| 885 | return -EINVAL; | 886 | return ERR_PTR(-EINVAL); |
| 886 | } | 887 | } |
| 887 | while (num_gpu_pages > 0) { | 888 | while (num_gpu_pages > 0) { |
| 888 | cur_pages = num_gpu_pages; | 889 | cur_pages = num_gpu_pages; |
| @@ -922,11 +923,13 @@ int r100_copy_blit(struct radeon_device *rdev, | |||
| 922 | RADEON_WAIT_2D_IDLECLEAN | | 923 | RADEON_WAIT_2D_IDLECLEAN | |
| 923 | RADEON_WAIT_HOST_IDLECLEAN | | 924 | RADEON_WAIT_HOST_IDLECLEAN | |
| 924 | RADEON_WAIT_DMA_GUI_IDLE); | 925 | RADEON_WAIT_DMA_GUI_IDLE); |
| 925 | if (fence) { | 926 | r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); |
| 926 | r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); | 927 | if (r) { |
| 928 | radeon_ring_unlock_undo(rdev, ring); | ||
| 929 | return ERR_PTR(r); | ||
| 927 | } | 930 | } |
| 928 | radeon_ring_unlock_commit(rdev, ring, false); | 931 | radeon_ring_unlock_commit(rdev, ring, false); |
| 929 | return r; | 932 | return fence; |
| 930 | } | 933 | } |
| 931 | 934 | ||
| 932 | static int r100_cp_wait_for_idle(struct radeon_device *rdev) | 935 | static int r100_cp_wait_for_idle(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 67780374a652..732d4938aab7 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c | |||
| @@ -80,13 +80,14 @@ static int r200_get_vtx_size_0(uint32_t vtx_fmt_0) | |||
| 80 | return vtx_size; | 80 | return vtx_size; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | int r200_copy_dma(struct radeon_device *rdev, | 83 | struct radeon_fence *r200_copy_dma(struct radeon_device *rdev, |
| 84 | uint64_t src_offset, | 84 | uint64_t src_offset, |
| 85 | uint64_t dst_offset, | 85 | uint64_t dst_offset, |
| 86 | unsigned num_gpu_pages, | 86 | unsigned num_gpu_pages, |
| 87 | struct radeon_fence **fence) | 87 | struct reservation_object *resv) |
| 88 | { | 88 | { |
| 89 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 89 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
| 90 | struct radeon_fence *fence; | ||
| 90 | uint32_t size; | 91 | uint32_t size; |
| 91 | uint32_t cur_size; | 92 | uint32_t cur_size; |
| 92 | int i, num_loops; | 93 | int i, num_loops; |
| @@ -98,7 +99,7 @@ int r200_copy_dma(struct radeon_device *rdev, | |||
| 98 | r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64); | 99 | r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64); |
| 99 | if (r) { | 100 | if (r) { |
| 100 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 101 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 101 | return r; | 102 | return ERR_PTR(r); |
| 102 | } | 103 | } |
| 103 | /* Must wait for 2D idle & clean before DMA or hangs might happen */ | 104 | /* Must wait for 2D idle & clean before DMA or hangs might happen */ |
| 104 | radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); | 105 | radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); |
| @@ -118,11 +119,13 @@ int r200_copy_dma(struct radeon_device *rdev, | |||
| 118 | } | 119 | } |
| 119 | radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); | 120 | radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); |
| 120 | radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE); | 121 | radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE); |
| 121 | if (fence) { | 122 | r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); |
| 122 | r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); | 123 | if (r) { |
| 124 | radeon_ring_unlock_undo(rdev, ring); | ||
| 125 | return ERR_PTR(r); | ||
| 123 | } | 126 | } |
| 124 | radeon_ring_unlock_commit(rdev, ring, false); | 127 | radeon_ring_unlock_commit(rdev, ring, false); |
| 125 | return r; | 128 | return fence; |
| 126 | } | 129 | } |
| 127 | 130 | ||
| 128 | 131 | ||
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a95ced569d84..5e9146b968b9 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -2894,12 +2894,13 @@ bool r600_semaphore_ring_emit(struct radeon_device *rdev, | |||
| 2894 | * Used by the radeon ttm implementation to move pages if | 2894 | * Used by the radeon ttm implementation to move pages if |
| 2895 | * registered as the asic copy callback. | 2895 | * registered as the asic copy callback. |
| 2896 | */ | 2896 | */ |
| 2897 | int r600_copy_cpdma(struct radeon_device *rdev, | 2897 | struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev, |
| 2898 | uint64_t src_offset, uint64_t dst_offset, | 2898 | uint64_t src_offset, uint64_t dst_offset, |
| 2899 | unsigned num_gpu_pages, | 2899 | unsigned num_gpu_pages, |
| 2900 | struct radeon_fence **fence) | 2900 | struct reservation_object *resv) |
| 2901 | { | 2901 | { |
| 2902 | struct radeon_semaphore *sem = NULL; | 2902 | struct radeon_semaphore *sem = NULL; |
| 2903 | struct radeon_fence *fence; | ||
| 2903 | int ring_index = rdev->asic->copy.blit_ring_index; | 2904 | int ring_index = rdev->asic->copy.blit_ring_index; |
| 2904 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 2905 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
| 2905 | u32 size_in_bytes, cur_size_in_bytes, tmp; | 2906 | u32 size_in_bytes, cur_size_in_bytes, tmp; |
| @@ -2909,7 +2910,7 @@ int r600_copy_cpdma(struct radeon_device *rdev, | |||
| 2909 | r = radeon_semaphore_create(rdev, &sem); | 2910 | r = radeon_semaphore_create(rdev, &sem); |
| 2910 | if (r) { | 2911 | if (r) { |
| 2911 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 2912 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 2912 | return r; | 2913 | return ERR_PTR(r); |
| 2913 | } | 2914 | } |
| 2914 | 2915 | ||
| 2915 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); | 2916 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); |
| @@ -2918,10 +2919,10 @@ int r600_copy_cpdma(struct radeon_device *rdev, | |||
| 2918 | if (r) { | 2919 | if (r) { |
| 2919 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 2920 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 2920 | radeon_semaphore_free(rdev, &sem, NULL); | 2921 | radeon_semaphore_free(rdev, &sem, NULL); |
| 2921 | return r; | 2922 | return ERR_PTR(r); |
| 2922 | } | 2923 | } |
| 2923 | 2924 | ||
| 2924 | radeon_semaphore_sync_to(sem, *fence); | 2925 | radeon_semaphore_sync_resv(sem, resv, false); |
| 2925 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 2926 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
| 2926 | 2927 | ||
| 2927 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 2928 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
| @@ -2948,17 +2949,17 @@ int r600_copy_cpdma(struct radeon_device *rdev, | |||
| 2948 | radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | 2949 | radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); |
| 2949 | radeon_ring_write(ring, WAIT_CP_DMA_IDLE_bit); | 2950 | radeon_ring_write(ring, WAIT_CP_DMA_IDLE_bit); |
| 2950 | 2951 | ||
| 2951 | r = radeon_fence_emit(rdev, fence, ring->idx); | 2952 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
| 2952 | if (r) { | 2953 | if (r) { |
| 2953 | radeon_ring_unlock_undo(rdev, ring); | 2954 | radeon_ring_unlock_undo(rdev, ring); |
| 2954 | radeon_semaphore_free(rdev, &sem, NULL); | 2955 | radeon_semaphore_free(rdev, &sem, NULL); |
| 2955 | return r; | 2956 | return ERR_PTR(r); |
| 2956 | } | 2957 | } |
| 2957 | 2958 | ||
| 2958 | radeon_ring_unlock_commit(rdev, ring, false); | 2959 | radeon_ring_unlock_commit(rdev, ring, false); |
| 2959 | radeon_semaphore_free(rdev, &sem, *fence); | 2960 | radeon_semaphore_free(rdev, &sem, fence); |
| 2960 | 2961 | ||
| 2961 | return r; | 2962 | return fence; |
| 2962 | } | 2963 | } |
| 2963 | 2964 | ||
| 2964 | int r600_set_surface_reg(struct radeon_device *rdev, int reg, | 2965 | int r600_set_surface_reg(struct radeon_device *rdev, int reg, |
diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c index 51fd98553eaf..fc54224ce87b 100644 --- a/drivers/gpu/drm/radeon/r600_dma.c +++ b/drivers/gpu/drm/radeon/r600_dma.c | |||
| @@ -436,18 +436,19 @@ void r600_dma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
| 436 | * @src_offset: src GPU address | 436 | * @src_offset: src GPU address |
| 437 | * @dst_offset: dst GPU address | 437 | * @dst_offset: dst GPU address |
| 438 | * @num_gpu_pages: number of GPU pages to xfer | 438 | * @num_gpu_pages: number of GPU pages to xfer |
| 439 | * @fence: radeon fence object | 439 | * @resv: reservation object to sync to |
| 440 | * | 440 | * |
| 441 | * Copy GPU paging using the DMA engine (r6xx). | 441 | * Copy GPU paging using the DMA engine (r6xx). |
| 442 | * Used by the radeon ttm implementation to move pages if | 442 | * Used by the radeon ttm implementation to move pages if |
| 443 | * registered as the asic copy callback. | 443 | * registered as the asic copy callback. |
| 444 | */ | 444 | */ |
| 445 | int r600_copy_dma(struct radeon_device *rdev, | 445 | struct radeon_fence *r600_copy_dma(struct radeon_device *rdev, |
| 446 | uint64_t src_offset, uint64_t dst_offset, | 446 | uint64_t src_offset, uint64_t dst_offset, |
| 447 | unsigned num_gpu_pages, | 447 | unsigned num_gpu_pages, |
| 448 | struct radeon_fence **fence) | 448 | struct reservation_object *resv) |
| 449 | { | 449 | { |
| 450 | struct radeon_semaphore *sem = NULL; | 450 | struct radeon_semaphore *sem = NULL; |
| 451 | struct radeon_fence *fence; | ||
| 451 | int ring_index = rdev->asic->copy.dma_ring_index; | 452 | int ring_index = rdev->asic->copy.dma_ring_index; |
| 452 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 453 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
| 453 | u32 size_in_dw, cur_size_in_dw; | 454 | u32 size_in_dw, cur_size_in_dw; |
| @@ -457,7 +458,7 @@ int r600_copy_dma(struct radeon_device *rdev, | |||
| 457 | r = radeon_semaphore_create(rdev, &sem); | 458 | r = radeon_semaphore_create(rdev, &sem); |
| 458 | if (r) { | 459 | if (r) { |
| 459 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 460 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 460 | return r; | 461 | return ERR_PTR(r); |
| 461 | } | 462 | } |
| 462 | 463 | ||
| 463 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; | 464 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; |
| @@ -466,10 +467,10 @@ int r600_copy_dma(struct radeon_device *rdev, | |||
| 466 | if (r) { | 467 | if (r) { |
| 467 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 468 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 468 | radeon_semaphore_free(rdev, &sem, NULL); | 469 | radeon_semaphore_free(rdev, &sem, NULL); |
| 469 | return r; | 470 | return ERR_PTR(r); |
| 470 | } | 471 | } |
| 471 | 472 | ||
| 472 | radeon_semaphore_sync_to(sem, *fence); | 473 | radeon_semaphore_sync_resv(sem, resv, false); |
| 473 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 474 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
| 474 | 475 | ||
| 475 | for (i = 0; i < num_loops; i++) { | 476 | for (i = 0; i < num_loops; i++) { |
| @@ -486,15 +487,15 @@ int r600_copy_dma(struct radeon_device *rdev, | |||
| 486 | dst_offset += cur_size_in_dw * 4; | 487 | dst_offset += cur_size_in_dw * 4; |
| 487 | } | 488 | } |
| 488 | 489 | ||
| 489 | r = radeon_fence_emit(rdev, fence, ring->idx); | 490 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
| 490 | if (r) { | 491 | if (r) { |
| 491 | radeon_ring_unlock_undo(rdev, ring); | 492 | radeon_ring_unlock_undo(rdev, ring); |
| 492 | radeon_semaphore_free(rdev, &sem, NULL); | 493 | radeon_semaphore_free(rdev, &sem, NULL); |
| 493 | return r; | 494 | return ERR_PTR(r); |
| 494 | } | 495 | } |
| 495 | 496 | ||
| 496 | radeon_ring_unlock_commit(rdev, ring, false); | 497 | radeon_ring_unlock_commit(rdev, ring, false); |
| 497 | radeon_semaphore_free(rdev, &sem, *fence); | 498 | radeon_semaphore_free(rdev, &sem, fence); |
| 498 | 499 | ||
| 499 | return r; | 500 | return fence; |
| 500 | } | 501 | } |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 79c988db79ad..2e41dc12cd00 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -585,8 +585,11 @@ bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, | |||
| 585 | struct radeon_semaphore *semaphore); | 585 | struct radeon_semaphore *semaphore); |
| 586 | bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, | 586 | bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, |
| 587 | struct radeon_semaphore *semaphore); | 587 | struct radeon_semaphore *semaphore); |
| 588 | void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore, | 588 | void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, |
| 589 | struct radeon_fence *fence); | 589 | struct radeon_fence *fence); |
| 590 | void radeon_semaphore_sync_resv(struct radeon_semaphore *semaphore, | ||
| 591 | struct reservation_object *resv, | ||
| 592 | bool shared); | ||
| 590 | int radeon_semaphore_sync_rings(struct radeon_device *rdev, | 593 | int radeon_semaphore_sync_rings(struct radeon_device *rdev, |
| 591 | struct radeon_semaphore *semaphore, | 594 | struct radeon_semaphore *semaphore, |
| 592 | int waiting_ring); | 595 | int waiting_ring); |
| @@ -1855,24 +1858,24 @@ struct radeon_asic { | |||
| 1855 | } display; | 1858 | } display; |
| 1856 | /* copy functions for bo handling */ | 1859 | /* copy functions for bo handling */ |
| 1857 | struct { | 1860 | struct { |
| 1858 | int (*blit)(struct radeon_device *rdev, | 1861 | struct radeon_fence *(*blit)(struct radeon_device *rdev, |
| 1859 | uint64_t src_offset, | 1862 | uint64_t src_offset, |
| 1860 | uint64_t dst_offset, | 1863 | uint64_t dst_offset, |
| 1861 | unsigned num_gpu_pages, | 1864 | unsigned num_gpu_pages, |
| 1862 | struct radeon_fence **fence); | 1865 | struct reservation_object *resv); |
| 1863 | u32 blit_ring_index; | 1866 | u32 blit_ring_index; |
| 1864 | int (*dma)(struct radeon_device *rdev, | 1867 | struct radeon_fence *(*dma)(struct radeon_device *rdev, |
| 1865 | uint64_t src_offset, | 1868 | uint64_t src_offset, |
| 1866 | uint64_t dst_offset, | 1869 | uint64_t dst_offset, |
| 1867 | unsigned num_gpu_pages, | 1870 | unsigned num_gpu_pages, |
| 1868 | struct radeon_fence **fence); | 1871 | struct reservation_object *resv); |
| 1869 | u32 dma_ring_index; | 1872 | u32 dma_ring_index; |
| 1870 | /* method used for bo copy */ | 1873 | /* method used for bo copy */ |
| 1871 | int (*copy)(struct radeon_device *rdev, | 1874 | struct radeon_fence *(*copy)(struct radeon_device *rdev, |
| 1872 | uint64_t src_offset, | 1875 | uint64_t src_offset, |
| 1873 | uint64_t dst_offset, | 1876 | uint64_t dst_offset, |
| 1874 | unsigned num_gpu_pages, | 1877 | unsigned num_gpu_pages, |
| 1875 | struct radeon_fence **fence); | 1878 | struct reservation_object *resv); |
| 1876 | /* ring used for bo copies */ | 1879 | /* ring used for bo copies */ |
| 1877 | u32 copy_ring_index; | 1880 | u32 copy_ring_index; |
| 1878 | } copy; | 1881 | } copy; |
| @@ -2833,9 +2836,9 @@ static inline void radeon_ring_write(struct radeon_ring *ring, uint32_t v) | |||
| 2833 | #define radeon_hdmi_setmode(rdev, e, m) (rdev)->asic->display.hdmi_setmode((e), (m)) | 2836 | #define radeon_hdmi_setmode(rdev, e, m) (rdev)->asic->display.hdmi_setmode((e), (m)) |
| 2834 | #define radeon_fence_ring_emit(rdev, r, fence) (rdev)->asic->ring[(r)]->emit_fence((rdev), (fence)) | 2837 | #define radeon_fence_ring_emit(rdev, r, fence) (rdev)->asic->ring[(r)]->emit_fence((rdev), (fence)) |
| 2835 | #define radeon_semaphore_ring_emit(rdev, r, cp, semaphore, emit_wait) (rdev)->asic->ring[(r)]->emit_semaphore((rdev), (cp), (semaphore), (emit_wait)) | 2838 | #define radeon_semaphore_ring_emit(rdev, r, cp, semaphore, emit_wait) (rdev)->asic->ring[(r)]->emit_semaphore((rdev), (cp), (semaphore), (emit_wait)) |
| 2836 | #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy.blit((rdev), (s), (d), (np), (f)) | 2839 | #define radeon_copy_blit(rdev, s, d, np, resv) (rdev)->asic->copy.blit((rdev), (s), (d), (np), (resv)) |
| 2837 | #define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy.dma((rdev), (s), (d), (np), (f)) | 2840 | #define radeon_copy_dma(rdev, s, d, np, resv) (rdev)->asic->copy.dma((rdev), (s), (d), (np), (resv)) |
| 2838 | #define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy.copy((rdev), (s), (d), (np), (f)) | 2841 | #define radeon_copy(rdev, s, d, np, resv) (rdev)->asic->copy.copy((rdev), (s), (d), (np), (resv)) |
| 2839 | #define radeon_copy_blit_ring_index(rdev) (rdev)->asic->copy.blit_ring_index | 2842 | #define radeon_copy_blit_ring_index(rdev) (rdev)->asic->copy.blit_ring_index |
| 2840 | #define radeon_copy_dma_ring_index(rdev) (rdev)->asic->copy.dma_ring_index | 2843 | #define radeon_copy_dma_ring_index(rdev) (rdev)->asic->copy.dma_ring_index |
| 2841 | #define radeon_copy_ring_index(rdev) (rdev)->asic->copy.copy_ring_index | 2844 | #define radeon_copy_ring_index(rdev) (rdev)->asic->copy.copy_ring_index |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 987a3b713e06..ca01bb8ea217 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -81,11 +81,11 @@ bool r100_semaphore_ring_emit(struct radeon_device *rdev, | |||
| 81 | int r100_cs_parse(struct radeon_cs_parser *p); | 81 | int r100_cs_parse(struct radeon_cs_parser *p); |
| 82 | void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 82 | void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 83 | uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg); | 83 | uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg); |
| 84 | int r100_copy_blit(struct radeon_device *rdev, | 84 | struct radeon_fence *r100_copy_blit(struct radeon_device *rdev, |
| 85 | uint64_t src_offset, | 85 | uint64_t src_offset, |
| 86 | uint64_t dst_offset, | 86 | uint64_t dst_offset, |
| 87 | unsigned num_gpu_pages, | 87 | unsigned num_gpu_pages, |
| 88 | struct radeon_fence **fence); | 88 | struct reservation_object *resv); |
| 89 | int r100_set_surface_reg(struct radeon_device *rdev, int reg, | 89 | int r100_set_surface_reg(struct radeon_device *rdev, int reg, |
| 90 | uint32_t tiling_flags, uint32_t pitch, | 90 | uint32_t tiling_flags, uint32_t pitch, |
| 91 | uint32_t offset, uint32_t obj_size); | 91 | uint32_t offset, uint32_t obj_size); |
| @@ -153,11 +153,11 @@ void r100_ring_hdp_flush(struct radeon_device *rdev, | |||
| 153 | /* | 153 | /* |
| 154 | * r200,rv250,rs300,rv280 | 154 | * r200,rv250,rs300,rv280 |
| 155 | */ | 155 | */ |
| 156 | extern int r200_copy_dma(struct radeon_device *rdev, | 156 | struct radeon_fence *r200_copy_dma(struct radeon_device *rdev, |
| 157 | uint64_t src_offset, | 157 | uint64_t src_offset, |
| 158 | uint64_t dst_offset, | 158 | uint64_t dst_offset, |
| 159 | unsigned num_gpu_pages, | 159 | unsigned num_gpu_pages, |
| 160 | struct radeon_fence **fence); | 160 | struct reservation_object *resv); |
| 161 | void r200_set_safe_registers(struct radeon_device *rdev); | 161 | void r200_set_safe_registers(struct radeon_device *rdev); |
| 162 | 162 | ||
| 163 | /* | 163 | /* |
| @@ -341,12 +341,14 @@ int r600_dma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); | |||
| 341 | void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | 341 | void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); |
| 342 | int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); | 342 | int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); |
| 343 | int r600_dma_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); | 343 | int r600_dma_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); |
| 344 | int r600_copy_cpdma(struct radeon_device *rdev, | 344 | struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev, |
| 345 | uint64_t src_offset, uint64_t dst_offset, | 345 | uint64_t src_offset, uint64_t dst_offset, |
| 346 | unsigned num_gpu_pages, struct radeon_fence **fence); | 346 | unsigned num_gpu_pages, |
| 347 | int r600_copy_dma(struct radeon_device *rdev, | 347 | struct reservation_object *resv); |
| 348 | uint64_t src_offset, uint64_t dst_offset, | 348 | struct radeon_fence *r600_copy_dma(struct radeon_device *rdev, |
| 349 | unsigned num_gpu_pages, struct radeon_fence **fence); | 349 | uint64_t src_offset, uint64_t dst_offset, |
| 350 | unsigned num_gpu_pages, | ||
| 351 | struct reservation_object *resv); | ||
| 350 | void r600_hpd_init(struct radeon_device *rdev); | 352 | void r600_hpd_init(struct radeon_device *rdev); |
| 351 | void r600_hpd_fini(struct radeon_device *rdev); | 353 | void r600_hpd_fini(struct radeon_device *rdev); |
| 352 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 354 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
| @@ -462,10 +464,10 @@ bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc); | |||
| 462 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); | 464 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); |
| 463 | void r700_cp_stop(struct radeon_device *rdev); | 465 | void r700_cp_stop(struct radeon_device *rdev); |
| 464 | void r700_cp_fini(struct radeon_device *rdev); | 466 | void r700_cp_fini(struct radeon_device *rdev); |
| 465 | int rv770_copy_dma(struct radeon_device *rdev, | 467 | struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev, |
| 466 | uint64_t src_offset, uint64_t dst_offset, | 468 | uint64_t src_offset, uint64_t dst_offset, |
| 467 | unsigned num_gpu_pages, | 469 | unsigned num_gpu_pages, |
| 468 | struct radeon_fence **fence); | 470 | struct reservation_object *resv); |
| 469 | u32 rv770_get_xclk(struct radeon_device *rdev); | 471 | u32 rv770_get_xclk(struct radeon_device *rdev); |
| 470 | int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); | 472 | int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); |
| 471 | int rv770_get_temp(struct radeon_device *rdev); | 473 | int rv770_get_temp(struct radeon_device *rdev); |
| @@ -536,10 +538,10 @@ void evergreen_dma_fence_ring_emit(struct radeon_device *rdev, | |||
| 536 | struct radeon_fence *fence); | 538 | struct radeon_fence *fence); |
| 537 | void evergreen_dma_ring_ib_execute(struct radeon_device *rdev, | 539 | void evergreen_dma_ring_ib_execute(struct radeon_device *rdev, |
| 538 | struct radeon_ib *ib); | 540 | struct radeon_ib *ib); |
| 539 | int evergreen_copy_dma(struct radeon_device *rdev, | 541 | struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev, |
| 540 | uint64_t src_offset, uint64_t dst_offset, | 542 | uint64_t src_offset, uint64_t dst_offset, |
| 541 | unsigned num_gpu_pages, | 543 | unsigned num_gpu_pages, |
| 542 | struct radeon_fence **fence); | 544 | struct reservation_object *resv); |
| 543 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable); | 545 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable); |
| 544 | void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); | 546 | void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); |
| 545 | int evergreen_get_temp(struct radeon_device *rdev); | 547 | int evergreen_get_temp(struct radeon_device *rdev); |
| @@ -701,10 +703,10 @@ int si_vm_init(struct radeon_device *rdev); | |||
| 701 | void si_vm_fini(struct radeon_device *rdev); | 703 | void si_vm_fini(struct radeon_device *rdev); |
| 702 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 704 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); |
| 703 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 705 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
| 704 | int si_copy_dma(struct radeon_device *rdev, | 706 | struct radeon_fence *si_copy_dma(struct radeon_device *rdev, |
| 705 | uint64_t src_offset, uint64_t dst_offset, | 707 | uint64_t src_offset, uint64_t dst_offset, |
| 706 | unsigned num_gpu_pages, | 708 | unsigned num_gpu_pages, |
| 707 | struct radeon_fence **fence); | 709 | struct reservation_object *resv); |
| 708 | 710 | ||
| 709 | void si_dma_vm_copy_pages(struct radeon_device *rdev, | 711 | void si_dma_vm_copy_pages(struct radeon_device *rdev, |
| 710 | struct radeon_ib *ib, | 712 | struct radeon_ib *ib, |
| @@ -760,14 +762,14 @@ bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, | |||
| 760 | struct radeon_semaphore *semaphore, | 762 | struct radeon_semaphore *semaphore, |
| 761 | bool emit_wait); | 763 | bool emit_wait); |
| 762 | void cik_sdma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | 764 | void cik_sdma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); |
| 763 | int cik_copy_dma(struct radeon_device *rdev, | 765 | struct radeon_fence *cik_copy_dma(struct radeon_device *rdev, |
| 764 | uint64_t src_offset, uint64_t dst_offset, | 766 | uint64_t src_offset, uint64_t dst_offset, |
| 765 | unsigned num_gpu_pages, | 767 | unsigned num_gpu_pages, |
| 766 | struct radeon_fence **fence); | 768 | struct reservation_object *resv); |
| 767 | int cik_copy_cpdma(struct radeon_device *rdev, | 769 | struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev, |
| 768 | uint64_t src_offset, uint64_t dst_offset, | 770 | uint64_t src_offset, uint64_t dst_offset, |
| 769 | unsigned num_gpu_pages, | 771 | unsigned num_gpu_pages, |
| 770 | struct radeon_fence **fence); | 772 | struct reservation_object *resv); |
| 771 | int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring); | 773 | int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring); |
| 772 | int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); | 774 | int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); |
| 773 | bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); | 775 | bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); |
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 69f5695bdab9..1e8855060fc7 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c | |||
| @@ -45,33 +45,29 @@ static int radeon_benchmark_do_move(struct radeon_device *rdev, unsigned size, | |||
| 45 | for (i = 0; i < n; i++) { | 45 | for (i = 0; i < n; i++) { |
| 46 | switch (flag) { | 46 | switch (flag) { |
| 47 | case RADEON_BENCHMARK_COPY_DMA: | 47 | case RADEON_BENCHMARK_COPY_DMA: |
| 48 | r = radeon_copy_dma(rdev, saddr, daddr, | 48 | fence = radeon_copy_dma(rdev, saddr, daddr, |
| 49 | size / RADEON_GPU_PAGE_SIZE, | 49 | size / RADEON_GPU_PAGE_SIZE, |
| 50 | &fence); | 50 | NULL); |
| 51 | break; | 51 | break; |
| 52 | case RADEON_BENCHMARK_COPY_BLIT: | 52 | case RADEON_BENCHMARK_COPY_BLIT: |
| 53 | r = radeon_copy_blit(rdev, saddr, daddr, | 53 | fence = radeon_copy_blit(rdev, saddr, daddr, |
| 54 | size / RADEON_GPU_PAGE_SIZE, | 54 | size / RADEON_GPU_PAGE_SIZE, |
| 55 | &fence); | 55 | NULL); |
| 56 | break; | 56 | break; |
| 57 | default: | 57 | default: |
| 58 | DRM_ERROR("Unknown copy method\n"); | 58 | DRM_ERROR("Unknown copy method\n"); |
| 59 | r = -EINVAL; | 59 | return -EINVAL; |
| 60 | } | 60 | } |
| 61 | if (r) | 61 | if (IS_ERR(fence)) |
| 62 | goto exit_do_move; | 62 | return PTR_ERR(fence); |
| 63 | |||
| 63 | r = radeon_fence_wait(fence, false); | 64 | r = radeon_fence_wait(fence, false); |
| 64 | if (r) | ||
| 65 | goto exit_do_move; | ||
| 66 | radeon_fence_unref(&fence); | 65 | radeon_fence_unref(&fence); |
| 66 | if (r) | ||
| 67 | return r; | ||
| 67 | } | 68 | } |
| 68 | end_jiffies = jiffies; | 69 | end_jiffies = jiffies; |
| 69 | r = jiffies_to_msecs(end_jiffies - start_jiffies); | 70 | return jiffies_to_msecs(end_jiffies - start_jiffies); |
| 70 | |||
| 71 | exit_do_move: | ||
| 72 | if (fence) | ||
| 73 | radeon_fence_unref(&fence); | ||
| 74 | return r; | ||
| 75 | } | 71 | } |
| 76 | 72 | ||
| 77 | 73 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 6e3d1c8f3483..f662de41ba49 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
| @@ -183,6 +183,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) | |||
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | p->relocs[i].tv.bo = &p->relocs[i].robj->tbo; | 185 | p->relocs[i].tv.bo = &p->relocs[i].robj->tbo; |
| 186 | p->relocs[i].tv.shared = !r->write_domain; | ||
| 186 | p->relocs[i].handle = r->handle; | 187 | p->relocs[i].handle = r->handle; |
| 187 | 188 | ||
| 188 | radeon_cs_buckets_add(&buckets, &p->relocs[i].tv.head, | 189 | radeon_cs_buckets_add(&buckets, &p->relocs[i].tv.head, |
| @@ -254,16 +255,13 @@ static void radeon_cs_sync_rings(struct radeon_cs_parser *p) | |||
| 254 | 255 | ||
| 255 | for (i = 0; i < p->nrelocs; i++) { | 256 | for (i = 0; i < p->nrelocs; i++) { |
| 256 | struct reservation_object *resv; | 257 | struct reservation_object *resv; |
| 257 | struct fence *fence; | ||
| 258 | 258 | ||
| 259 | if (!p->relocs[i].robj) | 259 | if (!p->relocs[i].robj) |
| 260 | continue; | 260 | continue; |
| 261 | 261 | ||
| 262 | resv = p->relocs[i].robj->tbo.resv; | 262 | resv = p->relocs[i].robj->tbo.resv; |
| 263 | fence = reservation_object_get_excl(resv); | 263 | radeon_semaphore_sync_resv(p->ib.semaphore, resv, |
| 264 | 264 | p->relocs[i].tv.shared); | |
| 265 | radeon_semaphore_sync_to(p->ib.semaphore, | ||
| 266 | (struct radeon_fence *)fence); | ||
| 267 | } | 265 | } |
| 268 | } | 266 | } |
| 269 | 267 | ||
| @@ -568,7 +566,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
| 568 | goto out; | 566 | goto out; |
| 569 | } | 567 | } |
| 570 | radeon_cs_sync_rings(parser); | 568 | radeon_cs_sync_rings(parser); |
| 571 | radeon_semaphore_sync_to(parser->ib.semaphore, vm->fence); | 569 | radeon_semaphore_sync_fence(parser->ib.semaphore, vm->fence); |
| 572 | 570 | ||
| 573 | if ((rdev->family >= CHIP_TAHITI) && | 571 | if ((rdev->family >= CHIP_TAHITI) && |
| 574 | (parser->chunk_const_ib_idx != -1)) { | 572 | (parser->chunk_const_ib_idx != -1)) { |
diff --git a/drivers/gpu/drm/radeon/radeon_ib.c b/drivers/gpu/drm/radeon/radeon_ib.c index 6fc7461d70c4..3f39fcca4d07 100644 --- a/drivers/gpu/drm/radeon/radeon_ib.c +++ b/drivers/gpu/drm/radeon/radeon_ib.c | |||
| @@ -145,7 +145,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, | |||
| 145 | if (ib->vm) { | 145 | if (ib->vm) { |
| 146 | struct radeon_fence *vm_id_fence; | 146 | struct radeon_fence *vm_id_fence; |
| 147 | vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring); | 147 | vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring); |
| 148 | radeon_semaphore_sync_to(ib->semaphore, vm_id_fence); | 148 | radeon_semaphore_sync_fence(ib->semaphore, vm_id_fence); |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | /* sync with other rings */ | 151 | /* sync with other rings */ |
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index 56d9fd66d8ae..5bfbd8372a3c 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c | |||
| @@ -96,15 +96,15 @@ bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx, | |||
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | /** | 98 | /** |
| 99 | * radeon_semaphore_sync_to - use the semaphore to sync to a fence | 99 | * radeon_semaphore_sync_fence - use the semaphore to sync to a fence |
| 100 | * | 100 | * |
| 101 | * @semaphore: semaphore object to add fence to | 101 | * @semaphore: semaphore object to add fence to |
| 102 | * @fence: fence to sync to | 102 | * @fence: fence to sync to |
| 103 | * | 103 | * |
| 104 | * Sync to the fence using this semaphore object | 104 | * Sync to the fence using this semaphore object |
| 105 | */ | 105 | */ |
| 106 | void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore, | 106 | void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, |
| 107 | struct radeon_fence *fence) | 107 | struct radeon_fence *fence) |
| 108 | { | 108 | { |
| 109 | struct radeon_fence *other; | 109 | struct radeon_fence *other; |
| 110 | 110 | ||
| @@ -116,6 +116,38 @@ void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore, | |||
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | /** | 118 | /** |
| 119 | * radeon_semaphore_sync_to - use the semaphore to sync to a reservation object | ||
| 120 | * | ||
| 121 | * @sema: semaphore object to add fence from reservation object to | ||
| 122 | * @resv: reservation object with embedded fence | ||
| 123 | * @shared: true if we should onyl sync to the exclusive fence | ||
| 124 | * | ||
| 125 | * Sync to the fence using this semaphore object | ||
| 126 | */ | ||
| 127 | void radeon_semaphore_sync_resv(struct radeon_semaphore *sema, | ||
| 128 | struct reservation_object *resv, | ||
| 129 | bool shared) | ||
| 130 | { | ||
| 131 | struct reservation_object_list *flist; | ||
| 132 | struct fence *f; | ||
| 133 | unsigned i; | ||
| 134 | |||
| 135 | /* always sync to the exclusive fence */ | ||
| 136 | f = reservation_object_get_excl(resv); | ||
| 137 | radeon_semaphore_sync_fence(sema, (struct radeon_fence*)f); | ||
| 138 | |||
| 139 | flist = reservation_object_get_list(resv); | ||
| 140 | if (shared || !flist) | ||
| 141 | return; | ||
| 142 | |||
| 143 | for (i = 0; i < flist->shared_count; ++i) { | ||
| 144 | f = rcu_dereference_protected(flist->shared[i], | ||
| 145 | reservation_object_held(resv)); | ||
| 146 | radeon_semaphore_sync_fence(sema, (struct radeon_fence*)f); | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | /** | ||
| 119 | * radeon_semaphore_sync_rings - sync ring to all registered fences | 151 | * radeon_semaphore_sync_rings - sync ring to all registered fences |
| 120 | * | 152 | * |
| 121 | * @rdev: radeon_device pointer | 153 | * @rdev: radeon_device pointer |
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 17bc3dced9f1..ce943e1a5e51 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c | |||
| @@ -116,11 +116,16 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) | |||
| 116 | radeon_bo_kunmap(gtt_obj[i]); | 116 | radeon_bo_kunmap(gtt_obj[i]); |
| 117 | 117 | ||
| 118 | if (ring == R600_RING_TYPE_DMA_INDEX) | 118 | if (ring == R600_RING_TYPE_DMA_INDEX) |
| 119 | r = radeon_copy_dma(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, &fence); | 119 | fence = radeon_copy_dma(rdev, gtt_addr, vram_addr, |
| 120 | size / RADEON_GPU_PAGE_SIZE, | ||
| 121 | NULL); | ||
| 120 | else | 122 | else |
| 121 | r = radeon_copy_blit(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, &fence); | 123 | fence = radeon_copy_blit(rdev, gtt_addr, vram_addr, |
| 122 | if (r) { | 124 | size / RADEON_GPU_PAGE_SIZE, |
| 125 | NULL); | ||
| 126 | if (IS_ERR(fence)) { | ||
| 123 | DRM_ERROR("Failed GTT->VRAM copy %d\n", i); | 127 | DRM_ERROR("Failed GTT->VRAM copy %d\n", i); |
| 128 | r = PTR_ERR(fence); | ||
| 124 | goto out_lclean_unpin; | 129 | goto out_lclean_unpin; |
| 125 | } | 130 | } |
| 126 | 131 | ||
| @@ -162,11 +167,16 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) | |||
| 162 | radeon_bo_kunmap(vram_obj); | 167 | radeon_bo_kunmap(vram_obj); |
| 163 | 168 | ||
| 164 | if (ring == R600_RING_TYPE_DMA_INDEX) | 169 | if (ring == R600_RING_TYPE_DMA_INDEX) |
| 165 | r = radeon_copy_dma(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, &fence); | 170 | fence = radeon_copy_dma(rdev, vram_addr, gtt_addr, |
| 171 | size / RADEON_GPU_PAGE_SIZE, | ||
| 172 | NULL); | ||
| 166 | else | 173 | else |
| 167 | r = radeon_copy_blit(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, &fence); | 174 | fence = radeon_copy_blit(rdev, vram_addr, gtt_addr, |
| 168 | if (r) { | 175 | size / RADEON_GPU_PAGE_SIZE, |
| 176 | NULL); | ||
| 177 | if (IS_ERR(fence)) { | ||
| 169 | DRM_ERROR("Failed VRAM->GTT copy %d\n", i); | 178 | DRM_ERROR("Failed VRAM->GTT copy %d\n", i); |
| 179 | r = PTR_ERR(fence); | ||
| 170 | goto out_lclean_unpin; | 180 | goto out_lclean_unpin; |
| 171 | } | 181 | } |
| 172 | 182 | ||
| @@ -222,7 +232,7 @@ out_lclean: | |||
| 222 | radeon_bo_unreserve(gtt_obj[i]); | 232 | radeon_bo_unreserve(gtt_obj[i]); |
| 223 | radeon_bo_unref(>t_obj[i]); | 233 | radeon_bo_unref(>t_obj[i]); |
| 224 | } | 234 | } |
| 225 | if (fence) | 235 | if (fence && !IS_ERR(fence)) |
| 226 | radeon_fence_unref(&fence); | 236 | radeon_fence_unref(&fence); |
| 227 | break; | 237 | break; |
| 228 | } | 238 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 62d1f4d730a2..eca2ce60d440 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
| @@ -233,6 +233,7 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, | |||
| 233 | struct radeon_device *rdev; | 233 | struct radeon_device *rdev; |
| 234 | uint64_t old_start, new_start; | 234 | uint64_t old_start, new_start; |
| 235 | struct radeon_fence *fence; | 235 | struct radeon_fence *fence; |
| 236 | unsigned num_pages; | ||
| 236 | int r, ridx; | 237 | int r, ridx; |
| 237 | 238 | ||
| 238 | rdev = radeon_get_rdev(bo->bdev); | 239 | rdev = radeon_get_rdev(bo->bdev); |
| @@ -269,12 +270,11 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, | |||
| 269 | 270 | ||
| 270 | BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0); | 271 | BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0); |
| 271 | 272 | ||
| 272 | /* sync other rings */ | 273 | num_pages = new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); |
| 273 | fence = (struct radeon_fence *)reservation_object_get_excl(bo->resv); | 274 | fence = radeon_copy(rdev, old_start, new_start, num_pages, bo->resv); |
| 274 | r = radeon_copy(rdev, old_start, new_start, | 275 | if (IS_ERR(fence)) |
| 275 | new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */ | 276 | return PTR_ERR(fence); |
| 276 | &fence); | 277 | |
| 277 | /* FIXME: handle copy error */ | ||
| 278 | r = ttm_bo_move_accel_cleanup(bo, &fence->base, | 278 | r = ttm_bo_move_accel_cleanup(bo, &fence->base, |
| 279 | evict, no_wait_gpu, new_mem); | 279 | evict, no_wait_gpu, new_mem); |
| 280 | radeon_fence_unref(&fence); | 280 | radeon_fence_unref(&fence); |
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 671ee566aa51..ce870959dff8 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c | |||
| @@ -143,6 +143,7 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, | |||
| 143 | list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM; | 143 | list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM; |
| 144 | list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM; | 144 | list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM; |
| 145 | list[0].tv.bo = &vm->page_directory->tbo; | 145 | list[0].tv.bo = &vm->page_directory->tbo; |
| 146 | list[0].tv.shared = false; | ||
| 146 | list[0].tiling_flags = 0; | 147 | list[0].tiling_flags = 0; |
| 147 | list[0].handle = 0; | 148 | list[0].handle = 0; |
| 148 | list_add(&list[0].tv.head, head); | 149 | list_add(&list[0].tv.head, head); |
| @@ -156,6 +157,7 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, | |||
| 156 | list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM; | 157 | list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM; |
| 157 | list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM; | 158 | list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM; |
| 158 | list[idx].tv.bo = &list[idx].robj->tbo; | 159 | list[idx].tv.bo = &list[idx].robj->tbo; |
| 160 | list[idx].tv.shared = false; | ||
| 159 | list[idx].tiling_flags = 0; | 161 | list[idx].tiling_flags = 0; |
| 160 | list[idx].handle = 0; | 162 | list[idx].handle = 0; |
| 161 | list_add(&list[idx++].tv.head, head); | 163 | list_add(&list[idx++].tv.head, head); |
| @@ -395,6 +397,7 @@ static int radeon_vm_clear_bo(struct radeon_device *rdev, | |||
| 395 | 397 | ||
| 396 | memset(&tv, 0, sizeof(tv)); | 398 | memset(&tv, 0, sizeof(tv)); |
| 397 | tv.bo = &bo->tbo; | 399 | tv.bo = &bo->tbo; |
| 400 | tv.shared = false; | ||
| 398 | 401 | ||
| 399 | INIT_LIST_HEAD(&head); | 402 | INIT_LIST_HEAD(&head); |
| 400 | list_add(&tv.head, &head); | 403 | list_add(&tv.head, &head); |
| @@ -693,15 +696,10 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, | |||
| 693 | incr, R600_PTE_VALID); | 696 | incr, R600_PTE_VALID); |
| 694 | 697 | ||
| 695 | if (ib.length_dw != 0) { | 698 | if (ib.length_dw != 0) { |
| 696 | struct fence *fence; | ||
| 697 | |||
| 698 | radeon_asic_vm_pad_ib(rdev, &ib); | 699 | radeon_asic_vm_pad_ib(rdev, &ib); |
| 699 | 700 | ||
| 700 | fence = reservation_object_get_excl(pd->tbo.resv); | 701 | radeon_semaphore_sync_resv(ib.semaphore, pd->tbo.resv, false); |
| 701 | radeon_semaphore_sync_to(ib.semaphore, | 702 | radeon_semaphore_sync_fence(ib.semaphore, vm->last_id_use); |
| 702 | (struct radeon_fence *)fence); | ||
| 703 | |||
| 704 | radeon_semaphore_sync_to(ib.semaphore, vm->last_id_use); | ||
| 705 | WARN_ON(ib.length_dw > ndw); | 703 | WARN_ON(ib.length_dw > ndw); |
| 706 | r = radeon_ib_schedule(rdev, &ib, NULL, false); | 704 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 707 | if (r) { | 705 | if (r) { |
| @@ -826,11 +824,8 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, | |||
| 826 | struct radeon_bo *pt = vm->page_tables[pt_idx].bo; | 824 | struct radeon_bo *pt = vm->page_tables[pt_idx].bo; |
| 827 | unsigned nptes; | 825 | unsigned nptes; |
| 828 | uint64_t pte; | 826 | uint64_t pte; |
| 829 | struct fence *fence; | ||
| 830 | 827 | ||
| 831 | fence = reservation_object_get_excl(pt->tbo.resv); | 828 | radeon_semaphore_sync_resv(ib->semaphore, pt->tbo.resv, false); |
| 832 | radeon_semaphore_sync_to(ib->semaphore, | ||
| 833 | (struct radeon_fence *)fence); | ||
| 834 | 829 | ||
| 835 | if ((addr & ~mask) == (end & ~mask)) | 830 | if ((addr & ~mask) == (end & ~mask)) |
| 836 | nptes = end - addr; | 831 | nptes = end - addr; |
| @@ -972,7 +967,7 @@ int radeon_vm_bo_update(struct radeon_device *rdev, | |||
| 972 | radeon_asic_vm_pad_ib(rdev, &ib); | 967 | radeon_asic_vm_pad_ib(rdev, &ib); |
| 973 | WARN_ON(ib.length_dw > ndw); | 968 | WARN_ON(ib.length_dw > ndw); |
| 974 | 969 | ||
| 975 | radeon_semaphore_sync_to(ib.semaphore, vm->fence); | 970 | radeon_semaphore_sync_fence(ib.semaphore, vm->fence); |
| 976 | r = radeon_ib_schedule(rdev, &ib, NULL, false); | 971 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 977 | if (r) { | 972 | if (r) { |
| 978 | radeon_ib_free(rdev, &ib); | 973 | radeon_ib_free(rdev, &ib); |
diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c index 74426ac2bb5c..c112764adfdf 100644 --- a/drivers/gpu/drm/radeon/rv770_dma.c +++ b/drivers/gpu/drm/radeon/rv770_dma.c | |||
| @@ -33,18 +33,19 @@ | |||
| 33 | * @src_offset: src GPU address | 33 | * @src_offset: src GPU address |
| 34 | * @dst_offset: dst GPU address | 34 | * @dst_offset: dst GPU address |
| 35 | * @num_gpu_pages: number of GPU pages to xfer | 35 | * @num_gpu_pages: number of GPU pages to xfer |
| 36 | * @fence: radeon fence object | 36 | * @resv: reservation object to sync to |
| 37 | * | 37 | * |
| 38 | * Copy GPU paging using the DMA engine (r7xx). | 38 | * Copy GPU paging using the DMA engine (r7xx). |
| 39 | * Used by the radeon ttm implementation to move pages if | 39 | * Used by the radeon ttm implementation to move pages if |
| 40 | * registered as the asic copy callback. | 40 | * registered as the asic copy callback. |
| 41 | */ | 41 | */ |
| 42 | int rv770_copy_dma(struct radeon_device *rdev, | 42 | struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev, |
| 43 | uint64_t src_offset, uint64_t dst_offset, | 43 | uint64_t src_offset, uint64_t dst_offset, |
| 44 | unsigned num_gpu_pages, | 44 | unsigned num_gpu_pages, |
| 45 | struct radeon_fence **fence) | 45 | struct reservation_object *resv) |
| 46 | { | 46 | { |
| 47 | struct radeon_semaphore *sem = NULL; | 47 | struct radeon_semaphore *sem = NULL; |
| 48 | struct radeon_fence *fence; | ||
| 48 | int ring_index = rdev->asic->copy.dma_ring_index; | 49 | int ring_index = rdev->asic->copy.dma_ring_index; |
| 49 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 50 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
| 50 | u32 size_in_dw, cur_size_in_dw; | 51 | u32 size_in_dw, cur_size_in_dw; |
| @@ -54,7 +55,7 @@ int rv770_copy_dma(struct radeon_device *rdev, | |||
| 54 | r = radeon_semaphore_create(rdev, &sem); | 55 | r = radeon_semaphore_create(rdev, &sem); |
| 55 | if (r) { | 56 | if (r) { |
| 56 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 57 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 57 | return r; | 58 | return ERR_PTR(r); |
| 58 | } | 59 | } |
| 59 | 60 | ||
| 60 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; | 61 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; |
| @@ -63,10 +64,10 @@ int rv770_copy_dma(struct radeon_device *rdev, | |||
| 63 | if (r) { | 64 | if (r) { |
| 64 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 65 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 65 | radeon_semaphore_free(rdev, &sem, NULL); | 66 | radeon_semaphore_free(rdev, &sem, NULL); |
| 66 | return r; | 67 | return ERR_PTR(r); |
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | radeon_semaphore_sync_to(sem, *fence); | 70 | radeon_semaphore_sync_resv(sem, resv, false); |
| 70 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 71 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
| 71 | 72 | ||
| 72 | for (i = 0; i < num_loops; i++) { | 73 | for (i = 0; i < num_loops; i++) { |
| @@ -83,15 +84,15 @@ int rv770_copy_dma(struct radeon_device *rdev, | |||
| 83 | dst_offset += cur_size_in_dw * 4; | 84 | dst_offset += cur_size_in_dw * 4; |
| 84 | } | 85 | } |
| 85 | 86 | ||
| 86 | r = radeon_fence_emit(rdev, fence, ring->idx); | 87 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
| 87 | if (r) { | 88 | if (r) { |
| 88 | radeon_ring_unlock_undo(rdev, ring); | 89 | radeon_ring_unlock_undo(rdev, ring); |
| 89 | radeon_semaphore_free(rdev, &sem, NULL); | 90 | radeon_semaphore_free(rdev, &sem, NULL); |
| 90 | return r; | 91 | return ERR_PTR(r); |
| 91 | } | 92 | } |
| 92 | 93 | ||
| 93 | radeon_ring_unlock_commit(rdev, ring, false); | 94 | radeon_ring_unlock_commit(rdev, ring, false); |
| 94 | radeon_semaphore_free(rdev, &sem, *fence); | 95 | radeon_semaphore_free(rdev, &sem, fence); |
| 95 | 96 | ||
| 96 | return r; | 97 | return fence; |
| 97 | } | 98 | } |
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c index 7c22baaf94db..9b0dfbc913f3 100644 --- a/drivers/gpu/drm/radeon/si_dma.c +++ b/drivers/gpu/drm/radeon/si_dma.c | |||
| @@ -218,18 +218,19 @@ void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
| 218 | * @src_offset: src GPU address | 218 | * @src_offset: src GPU address |
| 219 | * @dst_offset: dst GPU address | 219 | * @dst_offset: dst GPU address |
| 220 | * @num_gpu_pages: number of GPU pages to xfer | 220 | * @num_gpu_pages: number of GPU pages to xfer |
| 221 | * @fence: radeon fence object | 221 | * @resv: reservation object to sync to |
| 222 | * | 222 | * |
| 223 | * Copy GPU paging using the DMA engine (SI). | 223 | * Copy GPU paging using the DMA engine (SI). |
| 224 | * Used by the radeon ttm implementation to move pages if | 224 | * Used by the radeon ttm implementation to move pages if |
| 225 | * registered as the asic copy callback. | 225 | * registered as the asic copy callback. |
| 226 | */ | 226 | */ |
| 227 | int si_copy_dma(struct radeon_device *rdev, | 227 | struct radeon_fence *si_copy_dma(struct radeon_device *rdev, |
| 228 | uint64_t src_offset, uint64_t dst_offset, | 228 | uint64_t src_offset, uint64_t dst_offset, |
| 229 | unsigned num_gpu_pages, | 229 | unsigned num_gpu_pages, |
| 230 | struct radeon_fence **fence) | 230 | struct reservation_object *resv) |
| 231 | { | 231 | { |
| 232 | struct radeon_semaphore *sem = NULL; | 232 | struct radeon_semaphore *sem = NULL; |
| 233 | struct radeon_fence *fence; | ||
| 233 | int ring_index = rdev->asic->copy.dma_ring_index; | 234 | int ring_index = rdev->asic->copy.dma_ring_index; |
| 234 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 235 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
| 235 | u32 size_in_bytes, cur_size_in_bytes; | 236 | u32 size_in_bytes, cur_size_in_bytes; |
| @@ -239,7 +240,7 @@ int si_copy_dma(struct radeon_device *rdev, | |||
| 239 | r = radeon_semaphore_create(rdev, &sem); | 240 | r = radeon_semaphore_create(rdev, &sem); |
| 240 | if (r) { | 241 | if (r) { |
| 241 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 242 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 242 | return r; | 243 | return ERR_PTR(r); |
| 243 | } | 244 | } |
| 244 | 245 | ||
| 245 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); | 246 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); |
| @@ -248,10 +249,10 @@ int si_copy_dma(struct radeon_device *rdev, | |||
| 248 | if (r) { | 249 | if (r) { |
| 249 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 250 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
| 250 | radeon_semaphore_free(rdev, &sem, NULL); | 251 | radeon_semaphore_free(rdev, &sem, NULL); |
| 251 | return r; | 252 | return ERR_PTR(r); |
| 252 | } | 253 | } |
| 253 | 254 | ||
| 254 | radeon_semaphore_sync_to(sem, *fence); | 255 | radeon_semaphore_sync_resv(sem, resv, false); |
| 255 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 256 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
| 256 | 257 | ||
| 257 | for (i = 0; i < num_loops; i++) { | 258 | for (i = 0; i < num_loops; i++) { |
| @@ -268,16 +269,16 @@ int si_copy_dma(struct radeon_device *rdev, | |||
| 268 | dst_offset += cur_size_in_bytes; | 269 | dst_offset += cur_size_in_bytes; |
| 269 | } | 270 | } |
| 270 | 271 | ||
| 271 | r = radeon_fence_emit(rdev, fence, ring->idx); | 272 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
| 272 | if (r) { | 273 | if (r) { |
| 273 | radeon_ring_unlock_undo(rdev, ring); | 274 | radeon_ring_unlock_undo(rdev, ring); |
| 274 | radeon_semaphore_free(rdev, &sem, NULL); | 275 | radeon_semaphore_free(rdev, &sem, NULL); |
| 275 | return r; | 276 | return ERR_PTR(r); |
| 276 | } | 277 | } |
| 277 | 278 | ||
| 278 | radeon_ring_unlock_commit(rdev, ring, false); | 279 | radeon_ring_unlock_commit(rdev, ring, false); |
| 279 | radeon_semaphore_free(rdev, &sem, *fence); | 280 | radeon_semaphore_free(rdev, &sem, fence); |
| 280 | 281 | ||
| 281 | return r; | 282 | return fence; |
| 282 | } | 283 | } |
| 283 | 284 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c index adafc0f8ec06..8ce508e76208 100644 --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c | |||
| @@ -119,8 +119,14 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, | |||
| 119 | ret = -EBUSY; | 119 | ret = -EBUSY; |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | if (!ret) | 122 | if (!ret) { |
| 123 | continue; | 123 | if (!entry->shared) |
| 124 | continue; | ||
| 125 | |||
| 126 | ret = reservation_object_reserve_shared(bo->resv); | ||
| 127 | if (!ret) | ||
| 128 | continue; | ||
| 129 | } | ||
| 124 | 130 | ||
| 125 | /* uh oh, we lost out, drop every reservation and try | 131 | /* uh oh, we lost out, drop every reservation and try |
| 126 | * to only reserve this buffer, then start over if | 132 | * to only reserve this buffer, then start over if |
| @@ -136,6 +142,9 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, | |||
| 136 | ret = 0; | 142 | ret = 0; |
| 137 | } | 143 | } |
| 138 | 144 | ||
| 145 | if (!ret && entry->shared) | ||
| 146 | ret = reservation_object_reserve_shared(bo->resv); | ||
| 147 | |||
| 139 | if (unlikely(ret != 0)) { | 148 | if (unlikely(ret != 0)) { |
| 140 | if (ret == -EINTR) | 149 | if (ret == -EINTR) |
| 141 | ret = -ERESTARTSYS; | 150 | ret = -ERESTARTSYS; |
| @@ -183,7 +192,10 @@ void ttm_eu_fence_buffer_objects(struct ww_acquire_ctx *ticket, | |||
| 183 | 192 | ||
| 184 | list_for_each_entry(entry, list, head) { | 193 | list_for_each_entry(entry, list, head) { |
| 185 | bo = entry->bo; | 194 | bo = entry->bo; |
| 186 | reservation_object_add_excl_fence(bo->resv, fence); | 195 | if (entry->shared) |
| 196 | reservation_object_add_shared_fence(bo->resv, fence); | ||
| 197 | else | ||
| 198 | reservation_object_add_excl_fence(bo->resv, fence); | ||
| 187 | ttm_bo_add_to_lru(bo); | 199 | ttm_bo_add_to_lru(bo); |
| 188 | __ttm_bo_unreserve(bo); | 200 | __ttm_bo_unreserve(bo); |
| 189 | } | 201 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 0ceaddc8e4f7..b4de3b2a7cc5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
| @@ -346,6 +346,7 @@ static int vmw_bo_to_validate_list(struct vmw_sw_context *sw_context, | |||
| 346 | ++sw_context->cur_val_buf; | 346 | ++sw_context->cur_val_buf; |
| 347 | val_buf = &vval_buf->base; | 347 | val_buf = &vval_buf->base; |
| 348 | val_buf->bo = ttm_bo_reference(bo); | 348 | val_buf->bo = ttm_bo_reference(bo); |
| 349 | val_buf->shared = false; | ||
| 349 | list_add_tail(&val_buf->head, &sw_context->validate_nodes); | 350 | list_add_tail(&val_buf->head, &sw_context->validate_nodes); |
| 350 | vval_buf->validate_as_mob = validate_as_mob; | 351 | vval_buf->validate_as_mob = validate_as_mob; |
| 351 | } | 352 | } |
| @@ -2670,9 +2671,11 @@ void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, | |||
| 2670 | INIT_LIST_HEAD(&validate_list); | 2671 | INIT_LIST_HEAD(&validate_list); |
| 2671 | 2672 | ||
| 2672 | pinned_val.bo = ttm_bo_reference(dev_priv->pinned_bo); | 2673 | pinned_val.bo = ttm_bo_reference(dev_priv->pinned_bo); |
| 2674 | pinned_val.shared = false; | ||
| 2673 | list_add_tail(&pinned_val.head, &validate_list); | 2675 | list_add_tail(&pinned_val.head, &validate_list); |
| 2674 | 2676 | ||
| 2675 | query_val.bo = ttm_bo_reference(dev_priv->dummy_query_bo); | 2677 | query_val.bo = ttm_bo_reference(dev_priv->dummy_query_bo); |
| 2678 | query_val.shared = false; | ||
| 2676 | list_add_tail(&query_val.head, &validate_list); | 2679 | list_add_tail(&query_val.head, &validate_list); |
| 2677 | 2680 | ||
| 2678 | ret = ttm_eu_reserve_buffers(&ticket, &validate_list, false); | 2681 | ret = ttm_eu_reserve_buffers(&ticket, &validate_list, false); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index ff0e03b97753..26584316cb78 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
| @@ -133,6 +133,7 @@ static void vmw_resource_release(struct kref *kref) | |||
| 133 | struct ttm_validate_buffer val_buf; | 133 | struct ttm_validate_buffer val_buf; |
| 134 | 134 | ||
| 135 | val_buf.bo = bo; | 135 | val_buf.bo = bo; |
| 136 | val_buf.shared = false; | ||
| 136 | res->func->unbind(res, false, &val_buf); | 137 | res->func->unbind(res, false, &val_buf); |
| 137 | } | 138 | } |
| 138 | res->backup_dirty = false; | 139 | res->backup_dirty = false; |
| @@ -1219,6 +1220,7 @@ vmw_resource_check_buffer(struct vmw_resource *res, | |||
| 1219 | 1220 | ||
| 1220 | INIT_LIST_HEAD(&val_list); | 1221 | INIT_LIST_HEAD(&val_list); |
| 1221 | val_buf->bo = ttm_bo_reference(&res->backup->base); | 1222 | val_buf->bo = ttm_bo_reference(&res->backup->base); |
| 1223 | val_buf->shared = false; | ||
| 1222 | list_add_tail(&val_buf->head, &val_list); | 1224 | list_add_tail(&val_buf->head, &val_list); |
| 1223 | ret = ttm_eu_reserve_buffers(NULL, &val_list, interruptible); | 1225 | ret = ttm_eu_reserve_buffers(NULL, &val_list, interruptible); |
| 1224 | if (unlikely(ret != 0)) | 1226 | if (unlikely(ret != 0)) |
| @@ -1312,6 +1314,7 @@ int vmw_resource_do_evict(struct vmw_resource *res, bool interruptible) | |||
| 1312 | BUG_ON(!func->may_evict); | 1314 | BUG_ON(!func->may_evict); |
| 1313 | 1315 | ||
| 1314 | val_buf.bo = NULL; | 1316 | val_buf.bo = NULL; |
| 1317 | val_buf.shared = false; | ||
| 1315 | ret = vmw_resource_check_buffer(res, interruptible, &val_buf); | 1318 | ret = vmw_resource_check_buffer(res, interruptible, &val_buf); |
| 1316 | if (unlikely(ret != 0)) | 1319 | if (unlikely(ret != 0)) |
| 1317 | return ret; | 1320 | return ret; |
| @@ -1357,6 +1360,7 @@ int vmw_resource_validate(struct vmw_resource *res) | |||
| 1357 | return 0; | 1360 | return 0; |
| 1358 | 1361 | ||
| 1359 | val_buf.bo = NULL; | 1362 | val_buf.bo = NULL; |
| 1363 | val_buf.shared = false; | ||
| 1360 | if (res->backup) | 1364 | if (res->backup) |
| 1361 | val_buf.bo = &res->backup->base; | 1365 | val_buf.bo = &res->backup->base; |
| 1362 | do { | 1366 | do { |
| @@ -1474,6 +1478,7 @@ void vmw_resource_move_notify(struct ttm_buffer_object *bo, | |||
| 1474 | struct ttm_validate_buffer val_buf; | 1478 | struct ttm_validate_buffer val_buf; |
| 1475 | 1479 | ||
| 1476 | val_buf.bo = bo; | 1480 | val_buf.bo = bo; |
| 1481 | val_buf.shared = false; | ||
| 1477 | 1482 | ||
| 1478 | list_for_each_entry_safe(res, n, &dma_buf->res_list, mob_head) { | 1483 | list_for_each_entry_safe(res, n, &dma_buf->res_list, mob_head) { |
| 1479 | 1484 | ||
diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h index ff11a424f752..460441714413 100644 --- a/include/drm/ttm/ttm_execbuf_util.h +++ b/include/drm/ttm/ttm_execbuf_util.h | |||
| @@ -39,11 +39,13 @@ | |||
| 39 | * | 39 | * |
| 40 | * @head: list head for thread-private list. | 40 | * @head: list head for thread-private list. |
| 41 | * @bo: refcounted buffer object pointer. | 41 | * @bo: refcounted buffer object pointer. |
| 42 | * @shared: should the fence be added shared? | ||
| 42 | */ | 43 | */ |
| 43 | 44 | ||
| 44 | struct ttm_validate_buffer { | 45 | struct ttm_validate_buffer { |
| 45 | struct list_head head; | 46 | struct list_head head; |
| 46 | struct ttm_buffer_object *bo; | 47 | struct ttm_buffer_object *bo; |
| 48 | bool shared; | ||
| 47 | }; | 49 | }; |
| 48 | 50 | ||
| 49 | /** | 51 | /** |
