dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: j.glisse@gmail.com
To: dri-devel@lists.freedesktop.org
Cc: "Christian König" <deathsimple@vodafone.de>
Subject: [PATCH 01/18] drm/radeon: replace the per ring mutex with a global one
Date: Fri,  4 May 2012 18:43:42 -0400	[thread overview]
Message-ID: <1336171439-7672-2-git-send-email-j.glisse@gmail.com> (raw)
In-Reply-To: <1336171439-7672-1-git-send-email-j.glisse@gmail.com>

From: Christian König <deathsimple@vodafone.de>

A single global mutex for ring submissions seems sufficient.

Signed-off-by: Christian König <deathsimple@vodafone.de>
---
 drivers/gpu/drm/radeon/radeon.h           |    3 +-
 drivers/gpu/drm/radeon/radeon_device.c    |    3 +-
 drivers/gpu/drm/radeon/radeon_pm.c        |   10 +-----
 drivers/gpu/drm/radeon/radeon_ring.c      |   28 +++++++++++-------
 drivers/gpu/drm/radeon/radeon_semaphore.c |   42 +++++++++++++----------------
 5 files changed, 41 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 729d332..71d8af8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -667,7 +667,6 @@ struct radeon_ring {
 	uint64_t		gpu_addr;
 	uint32_t		align_mask;
 	uint32_t		ptr_mask;
-	struct mutex		mutex;
 	bool			ready;
 	u32			ptr_reg_shift;
 	u32			ptr_reg_mask;
@@ -806,6 +805,7 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsign
 int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw);
 void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *cp);
 void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *cp);
+void radeon_ring_undo(struct radeon_ring *ring);
 void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp);
 int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
 void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring);
@@ -1516,6 +1516,7 @@ struct radeon_device {
 	rwlock_t			fence_lock;
 	struct radeon_fence_driver	fence_drv[RADEON_NUM_RINGS];
 	struct radeon_semaphore_driver	semaphore_drv;
+	struct mutex			ring_lock;
 	struct radeon_ring		ring[RADEON_NUM_RINGS];
 	struct radeon_ib_pool		ib_pool;
 	struct radeon_irq		irq;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 93615d1..ad3a7fb 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -724,8 +724,7 @@ int radeon_device_init(struct radeon_device *rdev,
 	 * can recall function without having locking issues */
 	radeon_mutex_init(&rdev->cs_mutex);
 	radeon_mutex_init(&rdev->ib_pool.mutex);
-	for (i = 0; i < RADEON_NUM_RINGS; ++i)
-		mutex_init(&rdev->ring[i].mutex);
+	mutex_init(&rdev->ring_lock);
 	mutex_init(&rdev->dc_hw_i2c_mutex);
 	if (rdev->family >= CHIP_R600)
 		spin_lock_init(&rdev->ih.lock);
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index caa55d6..7c38745 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -252,10 +252,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
 
 	mutex_lock(&rdev->ddev->struct_mutex);
 	mutex_lock(&rdev->vram_mutex);
-	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
-		if (rdev->ring[i].ring_obj)
-			mutex_lock(&rdev->ring[i].mutex);
-	}
+	mutex_lock(&rdev->ring_lock);
 
 	/* gui idle int has issues on older chips it seems */
 	if (rdev->family >= CHIP_R600) {
@@ -311,10 +308,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
 
 	rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE;
 
-	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
-		if (rdev->ring[i].ring_obj)
-			mutex_unlock(&rdev->ring[i].mutex);
-	}
+	mutex_unlock(&rdev->ring_lock);
 	mutex_unlock(&rdev->vram_mutex);
 	mutex_unlock(&rdev->ddev->struct_mutex);
 }
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 2eb4c6e..a4d60ae 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -346,9 +346,9 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi
 		if (ndw < ring->ring_free_dw) {
 			break;
 		}
-		mutex_unlock(&ring->mutex);
+		mutex_unlock(&rdev->ring_lock);
 		r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring));
-		mutex_lock(&ring->mutex);
+		mutex_lock(&rdev->ring_lock);
 		if (r)
 			return r;
 	}
@@ -361,10 +361,10 @@ int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsig
 {
 	int r;
 
-	mutex_lock(&ring->mutex);
+	mutex_lock(&rdev->ring_lock);
 	r = radeon_ring_alloc(rdev, ring, ndw);
 	if (r) {
-		mutex_unlock(&ring->mutex);
+		mutex_unlock(&rdev->ring_lock);
 		return r;
 	}
 	return 0;
@@ -389,20 +389,25 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
 void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring)
 {
 	radeon_ring_commit(rdev, ring);
-	mutex_unlock(&ring->mutex);
+	mutex_unlock(&rdev->ring_lock);
 }
 
-void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring)
+void radeon_ring_undo(struct radeon_ring *ring)
 {
 	ring->wptr = ring->wptr_old;
-	mutex_unlock(&ring->mutex);
+}
+
+void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+	radeon_ring_undo(ring);
+	mutex_unlock(&rdev->ring_lock);
 }
 
 void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring)
 {
 	int r;
 
-	mutex_lock(&ring->mutex);
+	mutex_lock(&rdev->ring_lock);
 	radeon_ring_free_size(rdev, ring);
 	if (ring->rptr == ring->wptr) {
 		r = radeon_ring_alloc(rdev, ring, 1);
@@ -411,7 +416,7 @@ void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *
 			radeon_ring_commit(rdev, ring);
 		}
 	}
-	mutex_unlock(&ring->mutex);
+	mutex_unlock(&rdev->ring_lock);
 }
 
 void radeon_ring_lockup_update(struct radeon_ring *ring)
@@ -520,11 +525,12 @@ void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring)
 	int r;
 	struct radeon_bo *ring_obj;
 
-	mutex_lock(&ring->mutex);
+	mutex_lock(&rdev->ring_lock);
 	ring_obj = ring->ring_obj;
+	ring->ready = false;
 	ring->ring = NULL;
 	ring->ring_obj = NULL;
-	mutex_unlock(&ring->mutex);
+	mutex_unlock(&rdev->ring_lock);
 
 	if (ring_obj) {
 		r = radeon_bo_reserve(ring_obj, false);
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c
index 930a08a..c5b3d8e 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -39,7 +39,6 @@ static int radeon_semaphore_add_bo(struct radeon_device *rdev)
 	uint32_t *cpu_ptr;
 	int r, i;
 
-
 	bo = kmalloc(sizeof(struct radeon_semaphore_bo), GFP_KERNEL);
 	if (bo == NULL) {
 		return -ENOMEM;
@@ -154,13 +153,17 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev,
 				bool sync_to[RADEON_NUM_RINGS],
 				int dst_ring)
 {
-	int i, r;
+	int i = 0, r;
 
-	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
-		unsigned num_ops = i == dst_ring ? RADEON_NUM_RINGS : 1;
+	mutex_lock(&rdev->ring_lock);
+	r = radeon_ring_alloc(rdev, &rdev->ring[dst_ring], RADEON_NUM_RINGS * 8);
+	if (r) {
+		goto error;
+	}
 
-		/* don't lock unused rings */
-		if (!sync_to[i] && i != dst_ring)
+	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+		/* no need to sync to our own or unused rings */
+		if (!sync_to[i] || i == dst_ring)
 			continue;
 
 		/* prevent GPU deadlocks */
@@ -170,38 +173,31 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev,
 			goto error;
 		}
 
-                r = radeon_ring_lock(rdev, &rdev->ring[i], num_ops * 8);
-                if (r)
+		r = radeon_ring_alloc(rdev, &rdev->ring[i], 8);
+		if (r) {
 			goto error;
-	}
-
-	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
-		/* no need to sync to our own or unused rings */
-		if (!sync_to[i] || i == dst_ring)
-                        continue;
+		}
 
 		radeon_semaphore_emit_signal(rdev, i, semaphore);
 		radeon_semaphore_emit_wait(rdev, dst_ring, semaphore);
-	}
 
-	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
-
-		/* don't unlock unused rings */
-		if (!sync_to[i] && i != dst_ring)
-			continue;
-
-		radeon_ring_unlock_commit(rdev, &rdev->ring[i]);
+		radeon_ring_commit(rdev, &rdev->ring[i]);
 	}
 
+	radeon_ring_commit(rdev, &rdev->ring[dst_ring]);
+	mutex_unlock(&rdev->ring_lock);
+
 	return 0;
 
 error:
 	/* unlock all locks taken so far */
 	for (--i; i >= 0; --i) {
 		if (sync_to[i] || i == dst_ring) {
-			radeon_ring_unlock_undo(rdev, &rdev->ring[i]);
+			radeon_ring_undo(&rdev->ring[i]);
 		}
 	}
+	radeon_ring_undo(&rdev->ring[dst_ring]);
+	mutex_unlock(&rdev->ring_lock);
 	return r;
 }
 
-- 
1.7.7.6

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2012-05-04 22:44 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-04 22:43 [RFC] fence, sa allocator, ib pool, semaphore rework j.glisse
2012-05-04 22:43 ` j.glisse [this message]
2012-05-04 22:43 ` [PATCH 02/18] drm/radeon: convert fence to uint64_t v3 j.glisse
2012-05-04 22:43 ` [PATCH 03/18] drm/radeon: rework fence handling, drop fence list v5 j.glisse
2012-05-04 22:43 ` [PATCH 04/18] drm/radeon: hold ring emission mutex for lockup detection j.glisse
2012-05-04 22:43 ` [PATCH 05/18] drm/radeon: use inline functions to calc sa_bo addr j.glisse
2012-05-04 22:43 ` [PATCH 06/18] drm/radeon: add proper locking to the SA v3 j.glisse
2012-05-04 22:43 ` [PATCH 07/18] drm/radeon: add sub allocator debugfs file j.glisse
2012-05-04 22:43 ` [PATCH 08/18] drm/radeon: keep start and end offset in the SA j.glisse
2012-05-04 22:43 ` [PATCH 09/18] drm/radeon: make sa bo a stand alone object j.glisse
2012-05-04 22:43 ` [PATCH 10/18] drm/radeon: define new SA interface v2 j.glisse
2012-05-04 22:43 ` [PATCH 11/18] drm/radeon: use one wait queue for all rings add fence_wait_any j.glisse
2012-05-04 22:43 ` [PATCH 12/18] drm/radeon: multiple ring allocator j.glisse
2012-05-04 22:43 ` [PATCH 13/18] drm/radeon: simplify semaphore handling v2 j.glisse
2012-05-04 22:43 ` [PATCH 14/18] drm/radeon: rip out the ib pool j.glisse
2012-05-04 22:43 ` [PATCH 15/18] drm/radeon: immediately remove ttm-move semaphore j.glisse
2012-05-04 22:43 ` [PATCH 16/18] drm/radeon: move the semaphore from the fence into the ib j.glisse
2012-05-04 22:43 ` [PATCH 17/18] drm/radeon: remove r600 blit mutex v2 j.glisse
2012-05-04 22:43 ` [PATCH 18/18] drm/radeon: make the ib an inline object j.glisse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1336171439-7672-2-git-send-email-j.glisse@gmail.com \
    --to=j.glisse@gmail.com \
    --cc=deathsimple@vodafone.de \
    --cc=dri-devel@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox