[PATCH 1/4] drm/radeon: add pre and post IB sync

Christian König deathsimple at vodafone.de
Thu Aug 14 09:12:02 PDT 2014


From: Christian König <christian.koenig at amd.com>

This allows us to run different engines concurrently and
still have the fences sync to all operations as currently
required by TTM.

Signed-off-by: Christian König <christian.koenig at amd.com>
---
 drivers/gpu/drm/radeon/radeon.h    |  3 ++-
 drivers/gpu/drm/radeon/radeon_cs.c | 18 ++++++++++++------
 drivers/gpu/drm/radeon/radeon_ib.c | 30 ++++++++++++++++++++++--------
 drivers/gpu/drm/radeon/radeon_vm.c |  8 ++++----
 4 files changed, 40 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e715e0c..4579361 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -800,7 +800,8 @@ struct radeon_ib {
 	struct radeon_fence		*fence;
 	struct radeon_vm		*vm;
 	bool				is_const_ib;
-	struct radeon_semaphore		*semaphore;
+	struct radeon_semaphore		*presync;
+	struct radeon_semaphore		*postsync;
 };
 
 struct radeon_ring {
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index ee712c1..2be4fc5 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -228,11 +228,15 @@ static void radeon_cs_sync_rings(struct radeon_cs_parser *p)
 	int i;
 
 	for (i = 0; i < p->nrelocs; i++) {
-		if (!p->relocs[i].robj)
+		struct radeon_cs_reloc *reloc = &p->relocs[i];
+		struct radeon_bo *bo = reloc->robj;
+		struct radeon_fence *fence;
+
+		if (!bo)
 			continue;
 
-		radeon_semaphore_sync_to(p->ib.semaphore,
-					 p->relocs[i].robj->tbo.sync_obj);
+		fence = bo->tbo.sync_obj;
+		radeon_semaphore_sync_to(p->ib.presync, fence);
 	}
 }
 
@@ -252,9 +256,11 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
 	INIT_LIST_HEAD(&p->validated);
 	p->idx = 0;
 	p->ib.sa_bo = NULL;
-	p->ib.semaphore = NULL;
+	p->ib.presync = NULL;
+	p->ib.postsync = NULL;
 	p->const_ib.sa_bo = NULL;
-	p->const_ib.semaphore = NULL;
+	p->const_ib.presync = NULL;
+	p->const_ib.postsync = NULL;
 	p->chunk_ib_idx = -1;
 	p->chunk_relocs_idx = -1;
 	p->chunk_flags_idx = -1;
@@ -537,7 +543,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
 		goto out;
 	}
 	radeon_cs_sync_rings(parser);
-	radeon_semaphore_sync_to(parser->ib.semaphore, vm->fence);
+	radeon_semaphore_sync_to(parser->ib.presync, vm->fence);
 
 	if ((rdev->family >= CHIP_TAHITI) &&
 	    (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 65b0c21..be09d70 100644
--- a/drivers/gpu/drm/radeon/radeon_ib.c
+++ b/drivers/gpu/drm/radeon/radeon_ib.c
@@ -64,10 +64,13 @@ int radeon_ib_get(struct radeon_device *rdev, int ring,
 		return r;
 	}
 
-	r = radeon_semaphore_create(rdev, &ib->semaphore);
-	if (r) {
+	r = radeon_semaphore_create(rdev, &ib->presync);
+	if (r)
+		return r;
+
+	r = radeon_semaphore_create(rdev, &ib->postsync);
+	if (r)
 		return r;
-	}
 
 	ib->ring = ring;
 	ib->fence = NULL;
@@ -96,7 +99,8 @@ int radeon_ib_get(struct radeon_device *rdev, int ring,
  */
 void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib)
 {
-	radeon_semaphore_free(rdev, &ib->semaphore, ib->fence);
+	radeon_semaphore_free(rdev, &ib->presync, ib->fence);
+	radeon_semaphore_free(rdev, &ib->postsync, ib->fence);
 	radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence);
 	radeon_fence_unref(&ib->fence);
 }
@@ -144,11 +148,11 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
 	if (ib->vm) {
 		struct radeon_fence *vm_id_fence;
 		vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring);
-        	radeon_semaphore_sync_to(ib->semaphore, vm_id_fence);
+		radeon_semaphore_sync_to(ib->presync, vm_id_fence);
 	}
 
-	/* sync with other rings */
-	r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring);
+	/* sync with other rings before IB execution */
+	r = radeon_semaphore_sync_rings(rdev, ib->presync, ib->ring);
 	if (r) {
 		dev_err(rdev->dev, "failed to sync rings (%d)\n", r);
 		radeon_ring_unlock_undo(rdev, ring);
@@ -160,9 +164,19 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
 
 	if (const_ib) {
 		radeon_ring_ib_execute(rdev, const_ib->ring, const_ib);
-		radeon_semaphore_free(rdev, &const_ib->semaphore, NULL);
+		radeon_semaphore_free(rdev, &const_ib->presync, NULL);
+		radeon_semaphore_free(rdev, &const_ib->postsync, NULL);
 	}
 	radeon_ring_ib_execute(rdev, ib->ring, ib);
+
+	/* sync with other rings after IB execution */
+	r = radeon_semaphore_sync_rings(rdev, ib->postsync, ib->ring);
+	if (r) {
+		dev_err(rdev->dev, "failed to sync rings (%d)\n", r);
+		radeon_ring_unlock_undo(rdev, ring);
+		return r;
+	}
+
 	r = radeon_fence_emit(rdev, &ib->fence, ib->ring);
 	if (r) {
 		dev_err(rdev->dev, "failed to emit fence for new IB (%d)\n", r);
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index b2c336a..61f2e6a 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -696,8 +696,8 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
 
 	if (ib.length_dw != 0) {
 		radeon_asic_vm_pad_ib(rdev, &ib);
-		radeon_semaphore_sync_to(ib.semaphore, pd->tbo.sync_obj);
-		radeon_semaphore_sync_to(ib.semaphore, vm->last_id_use);
+		radeon_semaphore_sync_to(ib.presync, pd->tbo.sync_obj);
+		radeon_semaphore_sync_to(ib.presync, vm->last_id_use);
 		WARN_ON(ib.length_dw > ndw);
 		r = radeon_ib_schedule(rdev, &ib, NULL);
 		if (r) {
@@ -823,7 +823,7 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
 		unsigned nptes;
 		uint64_t pte;
 
-		radeon_semaphore_sync_to(ib->semaphore, pt->tbo.sync_obj);
+		radeon_semaphore_sync_to(ib->presync, pt->tbo.sync_obj);
 
 		if ((addr & ~mask) == (end & ~mask))
 			nptes = end - addr;
@@ -965,7 +965,7 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
 	radeon_asic_vm_pad_ib(rdev, &ib);
 	WARN_ON(ib.length_dw > ndw);
 
-	radeon_semaphore_sync_to(ib.semaphore, vm->fence);
+	radeon_semaphore_sync_to(ib.presync, vm->fence);
 	r = radeon_ib_schedule(rdev, &ib, NULL);
 	if (r) {
 		radeon_ib_free(rdev, &ib);
-- 
1.9.1



More information about the dri-devel mailing list