From: Maarten Lankhorst <maarten.lankhorst@canonical.com>
To: "dri-devel@lists.freedesktop.org"
<dri-devel@lists.freedesktop.org>,
"Christian König" <deathsimple@vodafone.de>
Subject: [PATCH 1/3] drm/radeon: take exclusive_lock in read mode during ring tests
Date: Mon, 18 Aug 2014 16:45:35 +0200 [thread overview]
Message-ID: <53F2118F.8000706@canonical.com> (raw)
This is needed for the next commit, because the lockup detection
will need the read lock to run.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
---
drivers/gpu/drm/radeon/radeon.h | 2 +-
drivers/gpu/drm/radeon/radeon_device.c | 61 ++++++++++++++++++++--------------
2 files changed, 37 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9e1732eb402c..1d806983ec7b 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -2312,7 +2312,7 @@ struct radeon_device {
bool need_dma32;
bool accel_working;
bool fastfb_working; /* IGP feature*/
- bool needs_reset;
+ bool needs_reset, in_reset;
struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
const struct firmware *me_fw; /* all family ME firmware */
const struct firmware *pfp_fw; /* r6/700 PFP firmware */
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index c8ea050c8fa4..82633fdd399d 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1671,29 +1671,34 @@ int radeon_gpu_reset(struct radeon_device *rdev)
down_write(&rdev->exclusive_lock);
if (!rdev->needs_reset) {
+ WARN_ON(rdev->in_reset);
up_write(&rdev->exclusive_lock);
return 0;
}
rdev->needs_reset = false;
-
- radeon_save_bios_scratch_regs(rdev);
- /* block TTM */
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
- radeon_pm_suspend(rdev);
- radeon_suspend(rdev);
- for (i = 0; i < RADEON_NUM_RINGS; ++i) {
- ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i],
- &ring_data[i]);
- if (ring_sizes[i]) {
- saved = true;
- dev_info(rdev->dev, "Saved %d dwords of commands "
- "on ring %d.\n", ring_sizes[i], i);
+ if (!rdev->in_reset) {
+ rdev->in_reset = true;
+
+ radeon_save_bios_scratch_regs(rdev);
+ /* block TTM */
+ radeon_pm_suspend(rdev);
+ radeon_suspend(rdev);
+
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i],
+ &ring_data[i]);
+ if (ring_sizes[i]) {
+ saved = true;
+ dev_info(rdev->dev, "Saved %d dwords of commands "
+ "on ring %d.\n", ring_sizes[i], i);
+ }
}
- }
+ } else
+ memset(ring_data, 0, sizeof(ring_data));
-retry:
r = radeon_asic_reset(rdev);
if (!r) {
dev_info(rdev->dev, "GPU reset succeeded, trying to resume\n");
@@ -1702,40 +1707,46 @@ retry:
radeon_restore_bios_scratch_regs(rdev);
- if (!r) {
+ if (!r && saved) {
for (i = 0; i < RADEON_NUM_RINGS; ++i) {
radeon_ring_restore(rdev, &rdev->ring[i],
ring_sizes[i], ring_data[i]);
- ring_sizes[i] = 0;
ring_data[i] = NULL;
}
+ } else {
+ radeon_fence_driver_force_completion(rdev);
+
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ kfree(ring_data[i]);
+ }
+ }
+ downgrade_write(&rdev->exclusive_lock);
+ ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
+ if (!r) {
r = radeon_ib_ring_tests(rdev);
if (r) {
dev_err(rdev->dev, "ib ring test failed (%d).\n", r);
if (saved) {
- saved = false;
+ /* if reset fails, try without saving data */
+ rdev->needs_reset = true;
radeon_suspend(rdev);
- goto retry;
+ up_read(&rdev->exclusive_lock);
+ return -EAGAIN;
}
}
- } else {
- radeon_fence_driver_force_completion(rdev);
- for (i = 0; i < RADEON_NUM_RINGS; ++i) {
- kfree(ring_data[i]);
- }
}
radeon_pm_resume(rdev);
drm_helper_resume_force_mode(rdev->ddev);
- ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
if (r) {
/* bad news, how to tell it to userspace ? */
dev_info(rdev->dev, "GPU reset failed\n");
}
- up_write(&rdev->exclusive_lock);
+ rdev->in_reset = false;
+ up_read(&rdev->exclusive_lock);
return r;
}
--
2.0.4
next reply other threads:[~2014-08-18 14:45 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-18 14:45 Maarten Lankhorst [this message]
2014-08-18 14:45 ` [PATCH 2/3] drm/radeon: handle lockup in delayed work, v3 Maarten Lankhorst
2014-08-18 15:12 ` Christian König
2014-08-18 15:28 ` Maarten Lankhorst
2014-08-18 16:20 ` Christian König
2014-08-18 14:46 ` [PATCH 3/3] drm/radeon: add timeout argument to radeon_fence_wait_seq Maarten Lankhorst
2014-08-18 15:02 ` [PATCH 1/3] drm/radeon: take exclusive_lock in read mode during ring tests Christian König
2014-08-18 15:24 ` [PATCH 1/3] drm/radeon: take exclusive_lock in read mode during ring tests, v2 Maarten Lankhorst
2014-08-18 16:03 ` [PATCH 1/3] drm/radeon: take exclusive_lock in read mode during ring tests Alex Deucher
2014-08-18 16:07 ` Christian König
2014-08-18 16:10 ` Alex Deucher
2014-08-18 20:02 ` Maarten Lankhorst
2014-08-18 20:56 ` 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=53F2118F.8000706@canonical.com \
--to=maarten.lankhorst@canonical.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.