aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2014-09-25 06:39:38 -0400
committerAlex Deucher <alexander.deucher@amd.com>2014-10-03 09:19:16 -0400
commit392a250bd080e296f97ccc7e91b051a6b5da0ff1 (patch)
tree9c945db20239a93068c5d6d0b26efda883e6ba24 /drivers/gpu
parenta0e847641cd7239661ff1b39db0afb0e2992026f (diff)
drm/radeon: cope with foreign fences inside the reservation object
Not the whole world is a radeon! :-) Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/cik.c2
-rw-r--r--drivers/gpu/drm/radeon/cik_sdma.c2
-rw-r--r--drivers/gpu/drm/radeon/evergreen_dma.c2
-rw-r--r--drivers/gpu/drm/radeon/r600.c2
-rw-r--r--drivers/gpu/drm/radeon/r600_dma.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon.h7
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c28
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_semaphore.c29
-rw-r--r--drivers/gpu/drm/radeon/radeon_vm.c4
-rw-r--r--drivers/gpu/drm/radeon/rv770_dma.c2
-rw-r--r--drivers/gpu/drm/radeon/si_dma.c2
12 files changed, 66 insertions, 25 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 05c2f43421aa..fc49a8d0fe00 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -3993,7 +3993,7 @@ struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev,
3993 return ERR_PTR(r); 3993 return ERR_PTR(r);
3994 } 3994 }
3995 3995
3996 radeon_semaphore_sync_resv(sem, resv, false); 3996 radeon_semaphore_sync_resv(rdev, sem, resv, false);
3997 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 3997 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
3998 3998
3999 for (i = 0; i < num_loops; i++) { 3999 for (i = 0; i < num_loops; i++) {
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c
index c01a6100c318..c473c9125295 100644
--- a/drivers/gpu/drm/radeon/cik_sdma.c
+++ b/drivers/gpu/drm/radeon/cik_sdma.c
@@ -571,7 +571,7 @@ struct radeon_fence *cik_copy_dma(struct radeon_device *rdev,
571 return ERR_PTR(r); 571 return ERR_PTR(r);
572 } 572 }
573 573
574 radeon_semaphore_sync_resv(sem, resv, false); 574 radeon_semaphore_sync_resv(rdev, sem, resv, false);
575 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 575 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
576 576
577 for (i = 0; i < num_loops; i++) { 577 for (i = 0; i < num_loops; i++) {
diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c
index 946f37d0b469..66bcfadeedd1 100644
--- a/drivers/gpu/drm/radeon/evergreen_dma.c
+++ b/drivers/gpu/drm/radeon/evergreen_dma.c
@@ -133,7 +133,7 @@ struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev,
133 return ERR_PTR(r); 133 return ERR_PTR(r);
134 } 134 }
135 135
136 radeon_semaphore_sync_resv(sem, resv, false); 136 radeon_semaphore_sync_resv(rdev, sem, resv, false);
137 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 137 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
138 138
139 for (i = 0; i < num_loops; i++) { 139 for (i = 0; i < num_loops; i++) {
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 25f367ac4637..f8eb519c3286 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2912,7 +2912,7 @@ struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev,
2912 return ERR_PTR(r); 2912 return ERR_PTR(r);
2913 } 2913 }
2914 2914
2915 radeon_semaphore_sync_resv(sem, resv, false); 2915 radeon_semaphore_sync_resv(rdev, sem, resv, false);
2916 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 2916 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
2917 2917
2918 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 2918 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c
index fc54224ce87b..a49db830a47f 100644
--- a/drivers/gpu/drm/radeon/r600_dma.c
+++ b/drivers/gpu/drm/radeon/r600_dma.c
@@ -470,7 +470,7 @@ struct radeon_fence *r600_copy_dma(struct radeon_device *rdev,
470 return ERR_PTR(r); 470 return ERR_PTR(r);
471 } 471 }
472 472
473 radeon_semaphore_sync_resv(sem, resv, false); 473 radeon_semaphore_sync_resv(rdev, sem, resv, false);
474 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 474 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
475 475
476 for (i = 0; i < num_loops; i++) { 476 for (i = 0; i < num_loops; i++) {
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 06d24b85003e..e01424fe2848 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -589,9 +589,10 @@ bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
589 struct radeon_semaphore *semaphore); 589 struct radeon_semaphore *semaphore);
590void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, 590void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore,
591 struct radeon_fence *fence); 591 struct radeon_fence *fence);
592void radeon_semaphore_sync_resv(struct radeon_semaphore *semaphore, 592int radeon_semaphore_sync_resv(struct radeon_device *rdev,
593 struct reservation_object *resv, 593 struct radeon_semaphore *semaphore,
594 bool shared); 594 struct reservation_object *resv,
595 bool shared);
595int radeon_semaphore_sync_rings(struct radeon_device *rdev, 596int radeon_semaphore_sync_rings(struct radeon_device *rdev,
596 struct radeon_semaphore *semaphore, 597 struct radeon_semaphore *semaphore,
597 int waiting_ring); 598 int waiting_ring);
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index f662de41ba49..1c893447d7cd 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -249,9 +249,9 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority
249 return 0; 249 return 0;
250} 250}
251 251
252static void radeon_cs_sync_rings(struct radeon_cs_parser *p) 252static int radeon_cs_sync_rings(struct radeon_cs_parser *p)
253{ 253{
254 int i; 254 int i, r = 0;
255 255
256 for (i = 0; i < p->nrelocs; i++) { 256 for (i = 0; i < p->nrelocs; i++) {
257 struct reservation_object *resv; 257 struct reservation_object *resv;
@@ -260,9 +260,13 @@ static void radeon_cs_sync_rings(struct radeon_cs_parser *p)
260 continue; 260 continue;
261 261
262 resv = p->relocs[i].robj->tbo.resv; 262 resv = p->relocs[i].robj->tbo.resv;
263 radeon_semaphore_sync_resv(p->ib.semaphore, resv, 263 r = radeon_semaphore_sync_resv(p->rdev, p->ib.semaphore, resv,
264 p->relocs[i].tv.shared); 264 p->relocs[i].tv.shared);
265
266 if (r)
267 break;
265 } 268 }
269 return r;
266} 270}
267 271
268/* XXX: note that this is called from the legacy UMS CS ioctl as well */ 272/* XXX: note that this is called from the legacy UMS CS ioctl as well */
@@ -472,13 +476,19 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
472 return r; 476 return r;
473 } 477 }
474 478
479 r = radeon_cs_sync_rings(parser);
480 if (r) {
481 if (r != -ERESTARTSYS)
482 DRM_ERROR("Failed to sync rings: %i\n", r);
483 return r;
484 }
485
475 if (parser->ring == R600_RING_TYPE_UVD_INDEX) 486 if (parser->ring == R600_RING_TYPE_UVD_INDEX)
476 radeon_uvd_note_usage(rdev); 487 radeon_uvd_note_usage(rdev);
477 else if ((parser->ring == TN_RING_TYPE_VCE1_INDEX) || 488 else if ((parser->ring == TN_RING_TYPE_VCE1_INDEX) ||
478 (parser->ring == TN_RING_TYPE_VCE2_INDEX)) 489 (parser->ring == TN_RING_TYPE_VCE2_INDEX))
479 radeon_vce_note_usage(rdev); 490 radeon_vce_note_usage(rdev);
480 491
481 radeon_cs_sync_rings(parser);
482 r = radeon_ib_schedule(rdev, &parser->ib, NULL, true); 492 r = radeon_ib_schedule(rdev, &parser->ib, NULL, true);
483 if (r) { 493 if (r) {
484 DRM_ERROR("Failed to schedule IB !\n"); 494 DRM_ERROR("Failed to schedule IB !\n");
@@ -565,7 +575,13 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
565 if (r) { 575 if (r) {
566 goto out; 576 goto out;
567 } 577 }
568 radeon_cs_sync_rings(parser); 578
579 r = radeon_cs_sync_rings(parser);
580 if (r) {
581 if (r != -ERESTARTSYS)
582 DRM_ERROR("Failed to sync rings: %i\n", r);
583 goto out;
584 }
569 radeon_semaphore_sync_fence(parser->ib.semaphore, vm->fence); 585 radeon_semaphore_sync_fence(parser->ib.semaphore, vm->fence);
570 586
571 if ((rdev->family >= CHIP_TAHITI) && 587 if ((rdev->family >= CHIP_TAHITI) &&
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index af9f2d6bd7d0..995167025282 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -541,6 +541,15 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
541 uint64_t seq[RADEON_NUM_RINGS] = {}; 541 uint64_t seq[RADEON_NUM_RINGS] = {};
542 long r; 542 long r;
543 543
544 /*
545 * This function should not be called on !radeon fences.
546 * If this is the case, it would mean this function can
547 * also be called on radeon fences belonging to another card.
548 * exclusive_lock is not held in that case.
549 */
550 if (WARN_ON_ONCE(!to_radeon_fence(&fence->base)))
551 return fence_wait(&fence->base, intr);
552
544 seq[fence->ring] = fence->seq; 553 seq[fence->ring] = fence->seq;
545 r = radeon_fence_wait_seq_timeout(fence->rdev, seq, intr, MAX_SCHEDULE_TIMEOUT); 554 r = radeon_fence_wait_seq_timeout(fence->rdev, seq, intr, MAX_SCHEDULE_TIMEOUT);
546 if (r < 0) { 555 if (r < 0) {
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c
index 4d4b0773638a..6deb08f045b7 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -124,27 +124,42 @@ void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore,
124 * 124 *
125 * Sync to the fence using this semaphore object 125 * Sync to the fence using this semaphore object
126 */ 126 */
127void radeon_semaphore_sync_resv(struct radeon_semaphore *sema, 127int radeon_semaphore_sync_resv(struct radeon_device *rdev,
128 struct reservation_object *resv, 128 struct radeon_semaphore *sema,
129 bool shared) 129 struct reservation_object *resv,
130 bool shared)
130{ 131{
131 struct reservation_object_list *flist; 132 struct reservation_object_list *flist;
132 struct fence *f; 133 struct fence *f;
134 struct radeon_fence *fence;
133 unsigned i; 135 unsigned i;
136 int r = 0;
134 137
135 /* always sync to the exclusive fence */ 138 /* always sync to the exclusive fence */
136 f = reservation_object_get_excl(resv); 139 f = reservation_object_get_excl(resv);
137 radeon_semaphore_sync_fence(sema, (struct radeon_fence*)f); 140 fence = f ? to_radeon_fence(f) : NULL;
141 if (fence && fence->rdev == rdev)
142 radeon_semaphore_sync_fence(sema, fence);
143 else if (f)
144 r = fence_wait(f, true);
138 145
139 flist = reservation_object_get_list(resv); 146 flist = reservation_object_get_list(resv);
140 if (shared || !flist) 147 if (shared || !flist || r)
141 return; 148 return r;
142 149
143 for (i = 0; i < flist->shared_count; ++i) { 150 for (i = 0; i < flist->shared_count; ++i) {
144 f = rcu_dereference_protected(flist->shared[i], 151 f = rcu_dereference_protected(flist->shared[i],
145 reservation_object_held(resv)); 152 reservation_object_held(resv));
146 radeon_semaphore_sync_fence(sema, (struct radeon_fence*)f); 153 fence = to_radeon_fence(f);
154 if (fence && fence->rdev == rdev)
155 radeon_semaphore_sync_fence(sema, fence);
156 else
157 r = fence_wait(f, true);
158
159 if (r)
160 break;
147 } 161 }
162 return r;
148} 163}
149 164
150/** 165/**
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index ce870959dff8..8af1a94e7448 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -698,7 +698,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
698 if (ib.length_dw != 0) { 698 if (ib.length_dw != 0) {
699 radeon_asic_vm_pad_ib(rdev, &ib); 699 radeon_asic_vm_pad_ib(rdev, &ib);
700 700
701 radeon_semaphore_sync_resv(ib.semaphore, pd->tbo.resv, false); 701 radeon_semaphore_sync_resv(rdev, ib.semaphore, pd->tbo.resv, false);
702 radeon_semaphore_sync_fence(ib.semaphore, vm->last_id_use); 702 radeon_semaphore_sync_fence(ib.semaphore, vm->last_id_use);
703 WARN_ON(ib.length_dw > ndw); 703 WARN_ON(ib.length_dw > ndw);
704 r = radeon_ib_schedule(rdev, &ib, NULL, false); 704 r = radeon_ib_schedule(rdev, &ib, NULL, false);
@@ -825,7 +825,7 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
825 unsigned nptes; 825 unsigned nptes;
826 uint64_t pte; 826 uint64_t pte;
827 827
828 radeon_semaphore_sync_resv(ib->semaphore, pt->tbo.resv, false); 828 radeon_semaphore_sync_resv(rdev, ib->semaphore, pt->tbo.resv, false);
829 829
830 if ((addr & ~mask) == (end & ~mask)) 830 if ((addr & ~mask) == (end & ~mask))
831 nptes = end - addr; 831 nptes = end - addr;
diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c
index c112764adfdf..7f34bad2e724 100644
--- a/drivers/gpu/drm/radeon/rv770_dma.c
+++ b/drivers/gpu/drm/radeon/rv770_dma.c
@@ -67,7 +67,7 @@ struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev,
67 return ERR_PTR(r); 67 return ERR_PTR(r);
68 } 68 }
69 69
70 radeon_semaphore_sync_resv(sem, resv, false); 70 radeon_semaphore_sync_resv(rdev, sem, resv, false);
71 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 71 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
72 72
73 for (i = 0; i < num_loops; i++) { 73 for (i = 0; i < num_loops; i++) {
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c
index 9b0dfbc913f3..b58f12b762d7 100644
--- a/drivers/gpu/drm/radeon/si_dma.c
+++ b/drivers/gpu/drm/radeon/si_dma.c
@@ -252,7 +252,7 @@ struct radeon_fence *si_copy_dma(struct radeon_device *rdev,
252 return ERR_PTR(r); 252 return ERR_PTR(r);
253 } 253 }
254 254
255 radeon_semaphore_sync_resv(sem, resv, false); 255 radeon_semaphore_sync_resv(rdev, sem, resv, false);
256 radeon_semaphore_sync_rings(rdev, sem, ring->idx); 256 radeon_semaphore_sync_rings(rdev, sem, ring->idx);
257 257
258 for (i = 0; i < num_loops; i++) { 258 for (i = 0; i < num_loops; i++) {