Message ID | 1348564534-5489-1-git-send-email-stefan.bader@canonical.com |
---|---|
State | New |
Headers | show |
On 25/09/12 10:15, Stefan Bader wrote: > I saw this on my older Dell 1521. Graphics were unusable and often > lead to complete lockups. Quick testing showed that this seemed to > be fixed in between 3.6-rc5 and 3.6-rc6. > From the few patches in between, the below stood out the most likely > one. It has been submitted to stable on Sep-20 but not yet was > picked up. But testing with this applied would make my Dell work > again. > > -Stefan > > > From b9a1600b7a1378f5182b6ca7b8d0d9d175950168 Mon Sep 17 00:00:00 2001 > From: =?UTF-8?q?Christian=20K=C3=B6nig?= <deathsimple@vodafone.de> > Date: Thu, 20 Sep 2012 16:57:00 +0200 > Subject: [PATCH] UBUNTU: (pre-stable) drm/radeon: make 64bit fences more robust v3 (3.5 stable) > MIME-Version: 1.0 > Content-Type: text/plain; charset=UTF-8 > Content-Transfer-Encoding: 8bit > > 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 > > This is the 3.5 stable version of the patch: > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=f492c171a38d77fc13a8998a0721f2da50835224 > 3.4 and previous kernels do not need to be patched. > > Signed-off-by: Christian König <deathsimple@vodafone.de> > Signed-off-by: Alex Deucher <alexander.deucher@amd.com> > > BugLink: http://bugs.launchpad.net/bugs/1029582 > > (cherry-picked from stable mailing list submission) > Signed-off-by: Stefan Bader <stefan.bader@canonical.com> > --- > drivers/gpu/drm/radeon/radeon_fence.c | 8 +++++--- > 1 file changed, 5 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c > index 11f5f40..71298ce 100644 > --- a/drivers/gpu/drm/radeon/radeon_fence.c > +++ b/drivers/gpu/drm/radeon/radeon_fence.c > @@ -75,7 +75,7 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) > > 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; > > @@ -102,13 +102,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].seq; > 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 > Nice find. Acked-by: Colin Ian King <colin.king@canonical.com>
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 11f5f40..71298ce 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -75,7 +75,7 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) 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; @@ -102,13 +102,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].seq; 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