Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/external/bsd/drm2/dist/drm/i915 Fix i915 locking around ...



details:   https://anonhg.NetBSD.org/src/rev/8f62980ef8c8
branches:  trunk
changeset: 331859:8f62980ef8c8
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Wed Aug 27 13:21:15 2014 +0000

description:
Fix i915 locking around error handling.

diffstat:

 sys/external/bsd/drm2/dist/drm/i915/i915_irq.c |  17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

diffs (82 lines):

diff -r 231f471d6d7d -r 8f62980ef8c8 sys/external/bsd/drm2/dist/drm/i915/i915_irq.c
--- a/sys/external/bsd/drm2/dist/drm/i915/i915_irq.c    Wed Aug 27 08:51:37 2014 +0000
+++ b/sys/external/bsd/drm2/dist/drm/i915/i915_irq.c    Wed Aug 27 13:21:15 2014 +0000
@@ -1099,7 +1099,9 @@
     {
        unsigned long flags;
        spin_lock_irqsave(&dev_priv->irq_lock, flags);
-       /* XXX Set a flag under the lock...  */
+       /*
+        * XXX Set a flag under the lock or push the lock out to callers.
+        */
        DRM_SPIN_WAKEUP_ALL(&ring->irq_queue, &dev_priv->irq_lock);
        spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
     }
@@ -1315,8 +1317,10 @@
        if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT |
                      GT_BSD_CS_ERROR_INTERRUPT |
                      GT_RENDER_CS_MASTER_ERROR_INTERRUPT)) {
+               spin_lock(&dev_priv->irq_lock);
                i915_handle_error(dev, false, "GT error interrupt 0x%08x",
                                  gt_iir);
+               spin_unlock(&dev_priv->irq_lock);
        }
 
        if (gt_iir & GT_PARITY_ERROR(dev))
@@ -1589,9 +1593,11 @@
                        notify_ring(dev_priv->dev, &dev_priv->ring[VECS]);
 
                if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) {
+                       spin_lock(&dev_priv->irq_lock);
                        i915_handle_error(dev_priv->dev, false,
                                          "VEBOX CS error interrupt 0x%08x",
                                          pm_iir);
+                       spin_unlock(&dev_priv->irq_lock);
                }
        }
 }
@@ -2357,6 +2363,8 @@
        va_list args;
        char error_msg[80];
 
+       assert_spin_locked(&dev_priv->irq_lock);
+
        va_start(args, fmt);
        vscnprintf(error_msg, sizeof(error_msg), fmt, args);
        va_end(args);
@@ -2734,6 +2742,8 @@
        if (!i915.enable_hangcheck)
                return;
 
+       spin_lock(&dev_priv->irq_lock);
+
        for_each_ring(ring, dev_priv, i) {
                u64 acthd;
                u32 seqno;
@@ -2747,9 +2757,7 @@
                if (ring->hangcheck.seqno == seqno) {
                        if (ring_idle(ring, seqno)) {
                                ring->hangcheck.action = HANGCHECK_IDLE;
-
 #ifdef __NetBSD__
-                               spin_lock(&dev_priv->irq_lock);
                                if (DRM_SPIN_WAITERS_P(&ring->irq_queue,
                                        &dev_priv->irq_lock)) {
                                        if (!test_and_set_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings)) {
@@ -2765,7 +2773,6 @@
                                } else {
                                        busy = false;
                                }
-                               spin_unlock(&dev_priv->irq_lock);
 #else
                                if (waitqueue_active(&ring->irq_queue)) {
                                        /* Issue a wake-up to catch stuck h/w. */
@@ -2845,6 +2852,8 @@
        if (rings_hung)
                return i915_handle_error(dev, true, "Ring hung");
 
+       spin_unlock(&dev_priv->irq_lock);
+
        if (busy_count)
                /* Reset timer case chip hangs without another request
                 * being added */



Home | Main Index | Thread Index | Old Index