aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Kuoppala <mika.kuoppala@linux.intel.com>2013-11-12 07:44:19 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-11-12 08:15:40 -0500
commit2ac0f45099d2d3b8918d63e1bac698b5cb272aa1 (patch)
tree9f7050823bae9f20ad5ce702ab4eb4a2d215cb59
parentf2d91a2c556479713abbefec237cad4bc1d54b0d (diff)
drm/i915: add i915_reset_count
reset_counter will be incremented twice per successful reset. Odd values mean reset is in progress and even values mean that reset has completed. Reset status ioctl introduced in following commit needs to deliver global reset count to userspace so use reset_counter to derive the actual reset count for the gpu Note that reset in progress is enough to increment the counter. v2: wedged equals reset in progress (Daniel Vetter) v3: Fixed stale comments (Damien Lespiau) Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com> Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h43
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c2
2 files changed, 23 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c546316ac649..4c0f751d1c88 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1069,34 +1069,30 @@ struct i915_gpu_error {
1069 unsigned long missed_irq_rings; 1069 unsigned long missed_irq_rings;
1070 1070
1071 /** 1071 /**
1072 * State variable and reset counter controlling the reset flow 1072 * State variable controlling the reset flow and count
1073 * 1073 *
1074 * Upper bits are for the reset counter. This counter is used by the 1074 * This is a counter which gets incremented when reset is triggered,
1075 * wait_seqno code to race-free noticed that a reset event happened and 1075 * and again when reset has been handled. So odd values (lowest bit set)
1076 * that it needs to restart the entire ioctl (since most likely the 1076 * means that reset is in progress and even values that
1077 * seqno it waited for won't ever signal anytime soon). 1077 * (reset_counter >> 1):th reset was successfully completed.
1078 *
1079 * If reset is not completed succesfully, the I915_WEDGE bit is
1080 * set meaning that hardware is terminally sour and there is no
1081 * recovery. All waiters on the reset_queue will be woken when
1082 * that happens.
1083 *
1084 * This counter is used by the wait_seqno code to notice that reset
1085 * event happened and it needs to restart the entire ioctl (since most
1086 * likely the seqno it waited for won't ever signal anytime soon).
1078 * 1087 *
1079 * This is important for lock-free wait paths, where no contended lock 1088 * This is important for lock-free wait paths, where no contended lock
1080 * naturally enforces the correct ordering between the bail-out of the 1089 * naturally enforces the correct ordering between the bail-out of the
1081 * waiter and the gpu reset work code. 1090 * waiter and the gpu reset work code.
1082 *
1083 * Lowest bit controls the reset state machine: Set means a reset is in
1084 * progress. This state will (presuming we don't have any bugs) decay
1085 * into either unset (successful reset) or the special WEDGED value (hw
1086 * terminally sour). All waiters on the reset_queue will be woken when
1087 * that happens.
1088 */ 1091 */
1089 atomic_t reset_counter; 1092 atomic_t reset_counter;
1090 1093
1091 /**
1092 * Special values/flags for reset_counter
1093 *
1094 * Note that the code relies on
1095 * I915_WEDGED & I915_RESET_IN_PROGRESS_FLAG
1096 * being true.
1097 */
1098#define I915_RESET_IN_PROGRESS_FLAG 1 1094#define I915_RESET_IN_PROGRESS_FLAG 1
1099#define I915_WEDGED 0xffffffff 1095#define I915_WEDGED (1 << 31)
1100 1096
1101 /** 1097 /**
1102 * Waitqueue to signal when the reset has completed. Used by clients 1098 * Waitqueue to signal when the reset has completed. Used by clients
@@ -2046,12 +2042,17 @@ int __must_check i915_gem_check_wedge(struct i915_gpu_error *error,
2046static inline bool i915_reset_in_progress(struct i915_gpu_error *error) 2042static inline bool i915_reset_in_progress(struct i915_gpu_error *error)
2047{ 2043{
2048 return unlikely(atomic_read(&error->reset_counter) 2044 return unlikely(atomic_read(&error->reset_counter)
2049 & I915_RESET_IN_PROGRESS_FLAG); 2045 & (I915_RESET_IN_PROGRESS_FLAG | I915_WEDGED));
2050} 2046}
2051 2047
2052static inline bool i915_terminally_wedged(struct i915_gpu_error *error) 2048static inline bool i915_terminally_wedged(struct i915_gpu_error *error)
2053{ 2049{
2054 return atomic_read(&error->reset_counter) == I915_WEDGED; 2050 return atomic_read(&error->reset_counter) & I915_WEDGED;
2051}
2052
2053static inline u32 i915_reset_count(struct i915_gpu_error *error)
2054{
2055 return ((atomic_read(&error->reset_counter) & ~I915_WEDGED) + 1) / 2;
2055} 2056}
2056 2057
2057void i915_gem_reset(struct drm_device *dev); 2058void i915_gem_reset(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index e14285bafbd4..19949e8b36c5 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1781,7 +1781,7 @@ static void i915_error_work_func(struct work_struct *work)
1781 kobject_uevent_env(&dev->primary->kdev.kobj, 1781 kobject_uevent_env(&dev->primary->kdev.kobj,
1782 KOBJ_CHANGE, reset_done_event); 1782 KOBJ_CHANGE, reset_done_event);
1783 } else { 1783 } else {
1784 atomic_set(&error->reset_counter, I915_WEDGED); 1784 atomic_set_mask(I915_WEDGED, &error->reset_counter);
1785 } 1785 }
1786 1786
1787 /* 1787 /*