diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-04-27 15:17:39 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-05-05 19:46:16 +0200 |
commit | 742cbee8049f434d8ae7908ee56fe4cad3db2658 (patch) | |
tree | 513e556a980b4cd53b08a5cf90815288d9b34c81 /drivers/gpu/drm/i915/i915_irq.c | |
parent | drm/i915: add interface to simulate gpu hangs (diff) | |
download | linux-742cbee8049f434d8ae7908ee56fe4cad3db2658.tar.xz linux-742cbee8049f434d8ae7908ee56fe4cad3db2658.zip |
drm/i915: rework dev->first_error locking
- reduce the irq disabled section, even for a debugfs file this was
way too long.
- always disable irqs when taking the lock.
v2: Thou shalt not mistake locking for reference counting, so:
- reference count the error_state to protect from concurent freeeing.
This will be only really used in the next patch.
Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 49e5d3ec5559..8334550fccf4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -850,10 +850,11 @@ i915_error_object_free(struct drm_i915_error_object *obj) kfree(obj); } -static void -i915_error_state_free(struct drm_device *dev, - struct drm_i915_error_state *error) +void +i915_error_state_free(struct kref *error_ref) { + struct drm_i915_error_state *error = container_of(error_ref, + typeof(*error), ref); int i; for (i = 0; i < ARRAY_SIZE(error->ring); i++) { @@ -1102,6 +1103,7 @@ static void i915_capture_error_state(struct drm_device *dev) DRM_INFO("capturing error event; look for more information in /debug/dri/%d/i915_error_state\n", dev->primary->index); + kref_init(&error->ref); error->eir = I915_READ(EIR); error->pgtbl_er = I915_READ(PGTBL_ER); @@ -1173,7 +1175,7 @@ static void i915_capture_error_state(struct drm_device *dev) spin_unlock_irqrestore(&dev_priv->error_lock, flags); if (error) - i915_error_state_free(dev, error); + i915_error_state_free(&error->ref); } void i915_destroy_error_state(struct drm_device *dev) @@ -1188,7 +1190,7 @@ void i915_destroy_error_state(struct drm_device *dev) spin_unlock_irqrestore(&dev_priv->error_lock, flags); if (error) - i915_error_state_free(dev, error); + kref_put(&error->ref, i915_error_state_free); } #else #define i915_capture_error_state(x) |