summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2012-09-13 08:33:47 (GMT)
committerAlex Deucher <alexander.deucher@amd.com>2012-09-13 20:17:49 (GMT)
commitf492c171a38d77fc13a8998a0721f2da50835224 (patch)
tree81b69eabeada3ba23674b43ff944384c8202313a
parent985f61f7ee647ad570c05eab0b74915da2ac8e19 (diff)
downloadlinux-f492c171a38d77fc13a8998a0721f2da50835224.tar.xz
drm/radeon: make 64bit fences more robust v3
Only increase the higher 32bits if we really detect a wrap around. v2: instead of increasing the higher 32bits just use the higher 32bits from the last emitted fence. v3: also use last emitted fence value as upper limit. The intention of this patch is to make fences as robust as they where before introducing 64bit fences. This is necessary because on older systems it looks like the fence value gets corrupted on initialization. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=51344 Should also fix: https://bugs.freedesktop.org/show_bug.cgi?id=54129 https://bugs.freedesktop.org/show_bug.cgi?id=54662 https://bugzilla.redhat.com/show_bug.cgi?id=846505 https://bugzilla.redhat.com/show_bug.cgi?id=845639 3.5 needs a separate patch due to changes in the fence code. Will send that out separately. Signed-off-by: Christian König <deathsimple@vodafone.de> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 7b737b9..2a59375 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -131,7 +131,7 @@ int radeon_fence_emit(struct radeon_device *rdev,
*/
void radeon_fence_process(struct radeon_device *rdev, int ring)
{
- uint64_t seq, last_seq;
+ uint64_t seq, last_seq, last_emitted;
unsigned count_loop = 0;
bool wake = false;
@@ -158,13 +158,15 @@ void radeon_fence_process(struct radeon_device *rdev, int ring)
*/
last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq);
do {
+ last_emitted = rdev->fence_drv[ring].sync_seq[ring];
seq = radeon_fence_read(rdev, ring);
seq |= last_seq & 0xffffffff00000000LL;
if (seq < last_seq) {
- seq += 0x100000000LL;
+ seq &= 0xffffffff;
+ seq |= last_emitted & 0xffffffff00000000LL;
}
- if (seq == last_seq) {
+ if (seq <= last_seq || seq > last_emitted) {
break;
}
/* If we loop over we don't want to return without