All of 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 15/27] drm/radeon: add general purpose fence signaled callback
Date: Tue,  1 May 2012 13:19:25 -0400	[thread overview]
Message-ID: <1335892777-7357-16-git-send-email-j.glisse@gmail.com> (raw)
In-Reply-To: <1335892777-7357-1-git-send-email-j.glisse@gmail.com>

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

Should be used to free resource that are protected by a fence.

Signed-off-by: Christian König <deathsimple@vodafone.de>
Reviewed-by: Jerome Glisse <jglisse@redhat.com>
---
 drivers/gpu/drm/radeon/radeon.h       |    8 ++++-
 drivers/gpu/drm/radeon/radeon_fence.c |   50 +++++++++++++++++++++++++++++---
 2 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index fbbbc5a..11cceb3 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -259,7 +259,6 @@ struct radeon_fence_driver {
 	wait_queue_head_t		queue;
 	struct list_head		created;
 	struct list_head		emitted;
-	struct list_head		signaled;
 	bool				initialized;
 };
 
@@ -274,6 +273,10 @@ struct radeon_fence {
 	/* RB, DMA, etc. */
 	int				ring;
 	struct radeon_semaphore		*semaphore;
+
+	/* called when fence is signaled */
+	void	(*signal_callback)(struct radeon_device *rdev, void *data);
+	void	*callback_data;
 };
 
 int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);
@@ -289,6 +292,9 @@ int radeon_fence_wait_empty(struct radeon_device *rdev, int ring);
 struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence);
 void radeon_fence_unref(struct radeon_fence **fence);
 int radeon_fence_count_emitted(struct radeon_device *rdev, int ring);
+bool radeon_fence_set_signal_callback(struct radeon_fence *fence,
+                                      void (*callback)(struct radeon_device *, void *),
+                                      void *data);
 
 /*
  * Tiling registers
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 2d13843..c58660a 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -83,7 +83,8 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
 	return 0;
 }
 
-static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring)
+static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring,
+				     struct list_head *signaled)
 {
 	struct radeon_fence *fence;
 	struct list_head *i, *n;
@@ -110,7 +111,7 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring)
 		i = n;
 		do {
 			n = i->prev;
-			list_move_tail(i, &rdev->fence_drv[ring].signaled);
+			list_move_tail(i, signaled);
 			fence = list_entry(i, struct radeon_fence, list);
 			fence->signaled = true;
 			i = n;
@@ -120,6 +121,20 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring)
 	return wake;
 }
 
+static void radeon_fence_process_signaled(struct radeon_device *rdev, struct list_head *signaled)
+{
+	struct radeon_fence *fence;
+	struct list_head *i, *n;
+
+	list_for_each_safe(i, n, signaled) {
+		fence = list_entry(i, struct radeon_fence, list);
+		list_del_init(&fence->list);
+		if (fence->signal_callback) {
+			fence->signal_callback(rdev, fence->callback_data);
+		}
+	}
+}
+
 static void radeon_fence_destroy(struct kref *kref)
 {
 	unsigned long irq_flags;
@@ -152,6 +167,8 @@ int radeon_fence_create(struct radeon_device *rdev,
 	(*fence)->seq = 0;
 	(*fence)->ring = ring;
 	(*fence)->semaphore = NULL;
+	(*fence)->signal_callback = NULL;
+	(*fence)->callback_data = NULL;
 	INIT_LIST_HEAD(&(*fence)->list);
 
 	write_lock_irqsave(&rdev->fence_lock, irq_flags);
@@ -164,6 +181,7 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
 {
 	unsigned long irq_flags;
 	bool signaled = false;
+	LIST_HEAD(siglist);
 
 	if (!fence)
 		return true;
@@ -179,10 +197,12 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
 		signaled = true;
 	}
 	if (!signaled) {
-		radeon_fence_poll_locked(fence->rdev, fence->ring);
+		radeon_fence_poll_locked(fence->rdev, fence->ring, &siglist);
 		signaled = fence->signaled;
 	}
 	write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags);
+	radeon_fence_process_signaled(fence->rdev, &siglist);
+
 	return signaled;
 }
 
@@ -341,10 +361,12 @@ void radeon_fence_process(struct radeon_device *rdev, int ring)
 {
 	unsigned long irq_flags;
 	bool wake;
+	LIST_HEAD(signaled);
 
 	write_lock_irqsave(&rdev->fence_lock, irq_flags);
-	wake = radeon_fence_poll_locked(rdev, ring);
+	wake = radeon_fence_poll_locked(rdev, ring, &signaled);
 	write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
+	radeon_fence_process_signaled(rdev, &signaled);
 	if (wake) {
 		wake_up_all(&rdev->fence_drv[ring].queue);
 	}
@@ -373,6 +395,25 @@ int radeon_fence_count_emitted(struct radeon_device *rdev, int ring)
 	return not_processed;
 }
 
+bool radeon_fence_set_signal_callback(struct radeon_fence *fence,
+				      void (*callback)(struct radeon_device *, void *),
+				      void *data)
+{
+	struct radeon_device *rdev = fence->rdev;
+	unsigned long irq_flags;
+	bool isset = false;
+
+	/* a readlock is suficient, cause this should be called only once */
+	read_lock_irqsave(&rdev->fence_lock, irq_flags);
+	if (fence->emitted && !fence->signaled) {
+		fence->signal_callback = callback;
+		fence->callback_data = data;
+		isset = true;
+	}
+	read_unlock_irqrestore(&rdev->fence_lock, irq_flags);
+	return isset;
+}
+
 int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring)
 {
 	unsigned long irq_flags;
@@ -413,7 +454,6 @@ static void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring)
 	atomic_set(&rdev->fence_drv[ring].seq, 0);
 	INIT_LIST_HEAD(&rdev->fence_drv[ring].created);
 	INIT_LIST_HEAD(&rdev->fence_drv[ring].emitted);
-	INIT_LIST_HEAD(&rdev->fence_drv[ring].signaled);
 	init_waitqueue_head(&rdev->fence_drv[ring].queue);
 	rdev->fence_drv[ring].initialized = false;
 }
-- 
1.7.7.6

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

  parent reply	other threads:[~2012-05-01 17:20 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <·>
2012-05-01 17:19 ` Include request for reset-rework branch v2 j.glisse
2012-05-01 17:19   ` [PATCH 01/27] drm/radeon: make radeon_gpu_is_lockup a per ring function j.glisse
2012-05-01 17:19   ` [PATCH 02/27] drm/radeon: replace gpu_lockup with ring->ready flag j.glisse
2012-05-01 17:19   ` [PATCH 03/27] drm/radeon: register ring debugfs handlers on init j.glisse
2012-05-01 17:19   ` [PATCH 04/27] drm/radeon: use central function for IB testing j.glisse
2012-05-01 17:19   ` [PATCH 05/27] drm/radeon: rework gpu lockup detection and processing j.glisse
2012-05-01 17:19   ` [PATCH 06/27] drm/radeon: fix a bug in the SA code j.glisse
2012-05-01 17:19   ` [PATCH 07/27] drm/radeon: add proper locking to the SA v3 j.glisse
2012-05-02  8:21     ` Christian König
2012-05-01 17:19   ` [PATCH 08/27] drm/radeon: add sub allocator debugfs file v2 j.glisse
2012-05-01 17:19   ` [PATCH 09/27] drm/radeon: improve sa allocator j.glisse
2012-05-01 17:19   ` [PATCH 10/27] drm/radeon: sa allocator add wakequeue j.glisse
2012-05-01 17:19   ` [PATCH 11/27] drm/radeon: use inline functions to calc sa_bo addr j.glisse
2012-05-01 17:19   ` [PATCH 12/27] drm/radeon: simplify semaphore handling j.glisse
2012-05-01 17:19   ` [PATCH 13/27] drm/radeon: return -ENOENT in fence_wait_next v2 j.glisse
2012-05-01 17:19   ` [PATCH 14/27] drm/radeon: rename fence_wait_last to fence_wait_empty j.glisse
2012-05-01 17:19   ` j.glisse [this message]
2012-05-01 17:19   ` [PATCH 16/27] drm/radeon: don't keep list of created fences j.glisse
2012-05-01 17:19   ` [PATCH 17/27] drm/radeon: add try_free callback to the SA v2 j.glisse
2012-05-01 17:19   ` [PATCH 18/27] drm/radeon: rip out the ib pool v3 j.glisse
2012-05-01 17:19   ` [PATCH 19/27] drm/radeon: fix a bug with the ring syncing code j.glisse
2012-05-01 17:19   ` [PATCH 20/27] drm/radeon: rework recursive gpu reset handling j.glisse
2012-05-01 17:19   ` [PATCH 21/27] drm/radeon: remove recursive mutex implementation j.glisse
2012-05-01 17:19   ` [PATCH 22/27] drm/radeon: move lockup detection code into radeon_ring.c j.glisse
2012-05-01 17:19   ` [PATCH 23/27] drm/radeon: make lockup timeout a module param j.glisse
2012-05-01 17:19   ` [PATCH 24/27] drm/radeon: unlock the ring mutex while waiting for the next fence j.glisse
2012-05-01 17:19   ` [PATCH 25/27] drm/radeon: make forcing ring activity a common function j.glisse
2012-05-01 17:19   ` [PATCH 26/27] drm/radeon: remove r300_gpu_is_lockup j.glisse
2012-05-01 17:19   ` [PATCH 27/27] drm/radeon: remove cayman_gpu_is_lockup j.glisse
2012-05-01 17:28   ` Include request for reset-rework branch v2 Jerome 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=1335892777-7357-16-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.