Module Name: src Committed By: riastradh Date: Wed Jan 15 13:53:32 UTC 2014
Modified Files: src/sys/external/bsd/drm2/dist/drm/i915 [riastradh-drm2]: i915_dma.c i915_gem.c i915_irq.c Log Message: Use dev_priv->irq_lock for ring->irq_queue, not dev->struct_mutex. We need to use a spin lock here, because we need to exclude interrupt handlers. To generate a diff of this commit: cvs rdiff -u -r1.1.1.1.2.34 -r1.1.1.1.2.35 \ src/sys/external/bsd/drm2/dist/drm/i915/i915_dma.c cvs rdiff -u -r1.1.1.1.2.16 -r1.1.1.1.2.17 \ src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c cvs rdiff -u -r1.1.1.1.2.7 -r1.1.1.1.2.8 \ src/sys/external/bsd/drm2/dist/drm/i915/i915_irq.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_dma.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_dma.c:1.1.1.1.2.34 src/sys/external/bsd/drm2/dist/drm/i915/i915_dma.c:1.1.1.1.2.35 --- src/sys/external/bsd/drm2/dist/drm/i915/i915_dma.c:1.1.1.1.2.34 Mon Dec 30 04:52:02 2013 +++ src/sys/external/bsd/drm2/dist/drm/i915/i915_dma.c Wed Jan 15 13:53:32 2014 @@ -795,9 +795,13 @@ static int i915_wait_irq(struct drm_devi if (ring->irq_get(ring)) { #ifdef __NetBSD__ - DRM_TIMED_WAIT_UNTIL(ret, &ring->irq_queue, &dev->struct_mutex, + unsigned long flags; + spin_lock_irqsave(&dev_priv->irq_lock, flags); + DRM_SPIN_TIMED_WAIT_UNTIL(ret, &ring->irq_queue, + &dev_priv->irq_lock, 3 * DRM_HZ, READ_BREADCRUMB(dev_priv) >= irq_nr); + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); #else DRM_WAIT_ON(ret, ring->irq_queue, 3 * DRM_HZ, READ_BREADCRUMB(dev_priv) >= irq_nr); Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c:1.1.1.1.2.16 src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c:1.1.1.1.2.17 --- src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c:1.1.1.1.2.16 Mon Dec 30 04:51:35 2013 +++ src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c Wed Jan 15 13:53:32 2014 @@ -1193,14 +1193,17 @@ static int __wait_seqno(struct intel_rin atomic_read(&dev_priv->mm.wedged)) do { #ifdef __NetBSD__ + unsigned long flags; + spin_lock_irqsave(&dev_priv->irq_lock, flags); /* * XXX This wait is always interruptible; we should * heed the flag `interruptible'. */ - DRM_TIMED_WAIT_UNTIL(end, &ring->irq_queue, - &ring->dev->struct_mutex, + DRM_SPIN_TIMED_WAIT_UNTIL(end, &ring->irq_queue, + &dev_priv->irq_lock, timeout_jiffies, EXIT_COND); + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); #else if (interruptible) end = wait_event_interruptible_timeout(ring->irq_queue, Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_irq.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_irq.c:1.1.1.1.2.7 src/sys/external/bsd/drm2/dist/drm/i915/i915_irq.c:1.1.1.1.2.8 --- src/sys/external/bsd/drm2/dist/drm/i915/i915_irq.c:1.1.1.1.2.7 Sun Sep 8 16:03:21 2013 +++ src/sys/external/bsd/drm2/dist/drm/i915/i915_irq.c Wed Jan 15 13:53:32 2014 @@ -355,7 +355,12 @@ static void notify_ring(struct drm_devic trace_i915_gem_request_complete(ring, ring->get_seqno(ring, false)); #ifdef __NetBSD__ - DRM_WAKEUP_ALL(&ring->irq_queue, &dev->struct_mutex); + { + unsigned long flags; + spin_lock_irqsave(&dev_priv->irq_lock, flags); + DRM_SPIN_WAKEUP_ALL(&ring->irq_queue, &dev_priv->irq_lock); + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + } #else wake_up_all(&ring->irq_queue); #endif @@ -1167,8 +1172,13 @@ static void i915_record_ring_state(struc } #ifdef __NetBSD__ - error->waiting[ring->id] = DRM_WAITERS_P(&ring->irq_queue, - &dev->struct_mutex); + { + unsigned long flags; + spin_lock_irqsave(&dev_priv->irq_lock, flags); + error->waiting[ring->id] = DRM_SPIN_WAITERS_P(&ring->irq_queue, + &dev_priv->irq_lock); + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + } #else error->waiting[ring->id] = waitqueue_active(&ring->irq_queue); #endif @@ -1487,7 +1497,8 @@ void i915_handle_error(struct drm_device */ for_each_ring(ring, dev_priv, i) #ifdef __NetBSD__ - DRM_WAKEUP_ALL(&ring->irq_queue, &dev->struct_mutex); + DRM_SPIN_WAKEUP_ALL(&ring->irq_queue, + &dev_priv->irq_lock); #else wake_up_all(&ring->irq_queue); #endif @@ -1697,20 +1708,20 @@ static bool i915_hangcheck_ring_idle(str /* Issue a wake-up to catch stuck h/w. */ #ifdef __NetBSD__ /* - * XXX mutex_lock here is a load of bollocks, but I'm - * not sure what invariants the irq_queue is actually - * relying on. + * XXX What invariants is the irq_queue relying on? */ - mutex_lock(&ring->dev->struct_mutex); - if (DRM_WAITERS_P(&ring->irq_queue, - &ring->dev->struct_mutex)) { + struct drm_i915_private *dev_priv = ring->dev->dev_private; + unsigned long flags; + spin_lock_irqsave(&dev_priv->irq_lock, flags); + if (DRM_SPIN_WAITERS_P(&ring->irq_queue, + &dev_priv->irq_lock)) { DRM_ERROR("Hangcheck timer elapsed... %s idle\n", ring->name); - DRM_WAKEUP_ALL(&ring->irq_queue, - &ring->dev->struct_mutex); + DRM_SPIN_WAKEUP_ALL(&ring->irq_queue, + &dev_priv->irq_lock); *err = true; } - mutex_unlock(&ring->dev->struct_mutex); + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); #else if (waitqueue_active(&ring->irq_queue)) { DRM_ERROR("Hangcheck timer elapsed... %s idle\n",