From: "Christian König" <deathsimple@vodafone.de>
To: airlied@redhat.com
Cc: "Christian König" <deathsimple@vodafone.de>,
dri-devel@lists.freedesktop.org
Subject: [PATCH 15/26] drm/radeon: add general purpose fence signaled callback
Date: Mon, 30 Apr 2012 16:50:53 +0200 [thread overview]
Message-ID: <1335797464-14317-16-git-send-email-deathsimple@vodafone.de> (raw)
In-Reply-To: <1335797464-14317-1-git-send-email-deathsimple@vodafone.de>
Should be used to free resource that are protected by a fence.
Signed-off-by: Christian König <deathsimple@vodafone.de>
---
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 ce22b01..74b6595 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.5.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2012-04-30 14:51 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-30 14:50 Include request for reset-rework branch Christian König
2012-04-30 14:50 ` [PATCH 01/26] drm/radeon: make radeon_gpu_is_lockup a per ring function Christian König
2012-04-30 14:50 ` [PATCH 02/26] drm/radeon: replace gpu_lockup with ring->ready flag Christian König
2012-04-30 14:50 ` [PATCH 03/26] drm/radeon: register ring debugfs handlers on init Christian König
2012-04-30 14:50 ` [PATCH 04/26] drm/radeon: use central function for IB testing Christian König
2012-04-30 14:50 ` [PATCH 05/26] drm/radeon: rework gpu lockup detection and processing Christian König
2012-04-30 14:50 ` [PATCH 06/26] drm/radeon: fix a bug in the SA code Christian König
2012-04-30 14:50 ` [PATCH 07/26] drm/radeon: add proper locking to the SA v2 Christian König
2012-04-30 15:58 ` Jerome Glisse
2012-05-01 12:31 ` Christian König
2012-04-30 14:50 ` [PATCH 08/26] drm/radeon: add sub allocator debugfs file Christian König
2012-04-30 14:50 ` [PATCH 09/26] drm/radeon: add biggest hole tracking and wakequeue to the sa v3 Christian König
2012-04-30 15:45 ` Jerome Glisse
2012-05-01 12:22 ` Christian König
2012-05-01 15:24 ` Jerome Glisse
2012-04-30 14:50 ` [PATCH 10/26] drm/radeon: add try_free callback to the SA Christian König
2012-04-30 14:50 ` [PATCH 11/26] drm/radeon: use inline functions to calc sa_bo addr Christian König
2012-04-30 14:50 ` [PATCH 12/26] drm/radeon: simplify semaphore handling Christian König
2012-04-30 14:50 ` [PATCH 13/26] drm/radeon: return -ENOENT in fence_wait_next v2 Christian König
2012-04-30 14:50 ` [PATCH 14/26] drm/radeon: rename fence_wait_last to fence_wait_empty Christian König
2012-04-30 14:50 ` Christian König [this message]
2012-04-30 14:50 ` [PATCH 16/26] drm/radeon: don't keep list of created fences Christian König
2012-04-30 14:50 ` [PATCH 17/26] drm/radeon: rip out the ib pool v2 Christian König
2012-04-30 14:50 ` [PATCH 18/26] drm/radeon: fix a bug with the ring syncing code Christian König
2012-04-30 14:50 ` [PATCH 19/26] drm/radeon: rework recursive gpu reset handling Christian König
2012-04-30 14:50 ` [PATCH 20/26] drm/radeon: remove recursive mutex implementation Christian König
2012-04-30 14:50 ` [PATCH 21/26] drm/radeon: move lockup detection code into radeon_ring.c Christian König
2012-04-30 14:51 ` [PATCH 22/26] drm/radeon: make lockup timeout a module param Christian König
2012-04-30 14:51 ` [PATCH 23/26] drm/radeon: unlock the ring mutex while waiting for the next fence Christian König
2012-04-30 14:51 ` [PATCH 24/26] drm/radeon: make forcing ring activity a common function Christian König
2012-04-30 14:51 ` [PATCH 25/26] drm/radeon: remove r300_gpu_is_lockup Christian König
2012-04-30 14:51 ` [PATCH 26/26] drm/radeon: remove cayman_gpu_is_lockup Christian König
2012-04-30 15:12 ` Include request for reset-rework branch Jerome Glisse
2012-04-30 15:12 ` Jerome Glisse
2012-04-30 15:37 ` Christian König
2012-04-30 16:26 ` Jerome Glisse
2012-05-01 13:38 ` Christian König
2012-05-01 13:37 ` Alex Deucher
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=1335797464-14317-16-git-send-email-deathsimple@vodafone.de \
--to=deathsimple@vodafone.de \
--cc=airlied@redhat.com \
--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