[PATCH 1/5] drm/radeon: rework and fix reset detection v2

2013-11-05 Thread Rafał Miłecki
2013/11/5 Christian K?nig :
> Am 03.11.2013 13:15, schrieb Rafa? Mi?ecki:
>
>> 2013/10/29 Christian K?nig :
>>>
>>> From: Christian K?nig 
>>>
>>> Stop fiddling with jiffies, always wait for RADEON_FENCE_JIFFIES_TIMEOUT.
>>> Consolidate the two wait sequence implementations into just one function.
>>> Activate all waiters and remember if the reset was already done instead
>>> of
>>> trying to reset from only one thread.
>>
>> With this patch I can't suspend my Samsung with:
>> 01:00.0 VGA compatible controller [0300]: Advanced Micro Devices [AMD]
>> nee ATI Blackcomb [Radeon HD 6900M series] [1002:6720]
>> anymore.
>>
>> The backlight goes off, activity LED goes off and then nothing.
>> Machine is still running and other lights (power, wifi, keyboard,
>> touchpad) are still working. Seems like a lockup to me.
>
>
> Does the attached patch help?

It does, thanks!

-- 
Rafa?


[PATCH 1/5] drm/radeon: rework and fix reset detection v2

2013-11-05 Thread Christian König
Am 03.11.2013 13:15, schrieb Rafa? Mi?ecki:
> 2013/10/29 Christian K?nig :
>> From: Christian K?nig 
>>
>> Stop fiddling with jiffies, always wait for RADEON_FENCE_JIFFIES_TIMEOUT.
>> Consolidate the two wait sequence implementations into just one function.
>> Activate all waiters and remember if the reset was already done instead of
>> trying to reset from only one thread.
> With this patch I can't suspend my Samsung with:
> 01:00.0 VGA compatible controller [0300]: Advanced Micro Devices [AMD]
> nee ATI Blackcomb [Radeon HD 6900M series] [1002:6720]
> anymore.
>
> The backlight goes off, activity LED goes off and then nothing.
> Machine is still running and other lights (power, wifi, keyboard,
> touchpad) are still working. Seems like a lockup to me.

Does the attached patch help?

Cheers,
Christian.
-- next part --
A non-text attachment was scrubbed...
Name: 0001-drm-radeon-fix-radeon_fence_wait_empty_locked.patch
Type: text/x-diff
Size: 1028 bytes
Desc: not available
URL: 



[PATCH 1/5] drm/radeon: rework and fix reset detection v2

2013-11-03 Thread Rafał Miłecki
2013/10/29 Christian K?nig :
> From: Christian K?nig 
>
> Stop fiddling with jiffies, always wait for RADEON_FENCE_JIFFIES_TIMEOUT.
> Consolidate the two wait sequence implementations into just one function.
> Activate all waiters and remember if the reset was already done instead of
> trying to reset from only one thread.

With this patch I can't suspend my Samsung with:
01:00.0 VGA compatible controller [0300]: Advanced Micro Devices [AMD]
nee ATI Blackcomb [Radeon HD 6900M series] [1002:6720]
anymore.

The backlight goes off, activity LED goes off and then nothing.
Machine is still running and other lights (power, wifi, keyboard,
touchpad) are still working. Seems like a lockup to me.


[PATCH 1/5] drm/radeon: rework and fix reset detection v2

2013-10-29 Thread Christian König
From: Christian K?nig 

Stop fiddling with jiffies, always wait for RADEON_FENCE_JIFFIES_TIMEOUT.
Consolidate the two wait sequence implementations into just one function.
Activate all waiters and remember if the reset was already done instead of
trying to reset from only one thread.

v2: clear reset flag earlier to avoid timeout in IB test

Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h|   2 +-
 drivers/gpu/drm/radeon/radeon_device.c |   8 +
 drivers/gpu/drm/radeon/radeon_fence.c  | 347 +++--
 3 files changed, 127 insertions(+), 230 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 24f4960..f289308 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -327,7 +327,6 @@ struct radeon_fence_driver {
/* sync_seq is protected by ring emission lock */
uint64_tsync_seq[RADEON_NUM_RINGS];
atomic64_t  last_seq;
-   unsigned long   last_activity;
boolinitialized;
 };

@@ -2170,6 +2169,7 @@ struct radeon_device {
boolneed_dma32;
boolaccel_working;
boolfastfb_working; /* IGP feature*/
+   boolneeds_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 841d0e0..3f35f21 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1549,6 +1549,14 @@ int radeon_gpu_reset(struct radeon_device *rdev)
int resched;

down_write(>exclusive_lock);
+
+   if (!rdev->needs_reset) {
+   up_write(>exclusive_lock);
+   return 0;
+   }
+
+   rdev->needs_reset = false;
+
radeon_save_bios_scratch_regs(rdev);
/* block TTM */
resched = ttm_bo_lock_delayed_workqueue(>mman.bdev);
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index ddb8f8e..b8f68b2 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -190,10 +190,8 @@ void radeon_fence_process(struct radeon_device *rdev, int 
ring)
}
} while (atomic64_xchg(>fence_drv[ring].last_seq, seq) > seq);

-   if (wake) {
-   rdev->fence_drv[ring].last_activity = jiffies;
+   if (wake)
wake_up_all(>fence_queue);
-   }
 }

 /**
@@ -212,13 +210,13 @@ static void radeon_fence_destroy(struct kref *kref)
 }

 /**
- * radeon_fence_seq_signaled - check if a fence sequeuce number has signaled
+ * radeon_fence_seq_signaled - check if a fence sequence number has signaled
  *
  * @rdev: radeon device pointer
  * @seq: sequence number
  * @ring: ring index the fence is associated with
  *
- * Check if the last singled fence sequnce number is >= the requested
+ * Check if the last signaled fence sequnce number is >= the requested
  * sequence number (all asics).
  * Returns true if the fence has signaled (current fence value
  * is >= requested value) or false if it has not (current fence
@@ -263,113 +261,131 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
 }

 /**
- * radeon_fence_wait_seq - wait for a specific sequence number
+ * radeon_fence_any_seq_signaled - check if any sequence number is signaled
  *
  * @rdev: radeon device pointer
- * @target_seq: sequence number we want to wait for
- * @ring: ring index the fence is associated with
+ * @seq: sequence numbers
+ *
+ * Check if the last signaled fence sequnce number is >= the requested
+ * sequence number (all asics).
+ * Returns true if any has signaled (current value is >= requested value)
+ * or false if it has not. Helper function for radeon_fence_wait_seq.
+ */
+static bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq)
+{
+   unsigned i;
+
+   for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+   if (seq[i] && radeon_fence_seq_signaled(rdev, seq[i], i))
+   return true;
+   }
+   return false;
+}
+
+/**
+ * radeon_fence_wait_seq - wait for a specific sequence numbers
+ *
+ * @rdev: radeon device pointer
+ * @target_seq: sequence number(s) we want to wait for
  * @intr: use interruptable sleep
  * @lock_ring: whether the ring should be locked or not
  *
- * Wait for the requested sequence number to be written (all asics).
+ * Wait for the requested sequence number(s) to be written by any ring
+ * (all asics).  Sequnce number array is indexed by ring id.
  * @intr selects whether to use interruptable (true) or non-interruptable
  * (false)