aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2008-09-01 19:45:29 -0400
committerDave Airlie <airlied@linux.ie>2008-10-17 17:10:51 -0400
commit546b0974c39657017407c86fe79811100b60700d (patch)
tree42ae164d23ecaa1cb78ad87ad9603e0bdd29740d /drivers/gpu/drm/i915/i915_irq.c
parented4c9c4acf948b42b138747fcb8843ecb1a24ce4 (diff)
i915: Use struct_mutex to protect ring in GEM mode.
In the conversion for GEM, we had stopped using the hardware lock to protect ring usage, since it was all internal to the DRM now. However, some paths weren't converted to using struct_mutex to prevent multiple threads from concurrently working on the ring, in particular between the vblank swap handler and ioctls. Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index f295bdf16e2d..d04c526410a9 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -349,6 +349,21 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
349 return count; 349 return count;
350} 350}
351 351
352void
353i915_gem_vblank_work_handler(struct work_struct *work)
354{
355 drm_i915_private_t *dev_priv;
356 struct drm_device *dev;
357
358 dev_priv = container_of(work, drm_i915_private_t,
359 mm.vblank_work);
360 dev = dev_priv->dev;
361
362 mutex_lock(&dev->struct_mutex);
363 i915_vblank_tasklet(dev);
364 mutex_unlock(&dev->struct_mutex);
365}
366
352irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) 367irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
353{ 368{
354 struct drm_device *dev = (struct drm_device *) arg; 369 struct drm_device *dev = (struct drm_device *) arg;
@@ -422,8 +437,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
422 if (iir & I915_ASLE_INTERRUPT) 437 if (iir & I915_ASLE_INTERRUPT)
423 opregion_asle_intr(dev); 438 opregion_asle_intr(dev);
424 439
425 if (vblank && dev_priv->swaps_pending > 0) 440 if (vblank && dev_priv->swaps_pending > 0) {
426 drm_locked_tasklet(dev, i915_vblank_tasklet); 441 if (dev_priv->ring.ring_obj == NULL)
442 drm_locked_tasklet(dev, i915_vblank_tasklet);
443 else
444 schedule_work(&dev_priv->mm.vblank_work);
445 }
427 446
428 return IRQ_HANDLED; 447 return IRQ_HANDLED;
429} 448}
@@ -514,14 +533,15 @@ int i915_irq_emit(struct drm_device *dev, void *data,
514 drm_i915_irq_emit_t *emit = data; 533 drm_i915_irq_emit_t *emit = data;
515 int result; 534 int result;
516 535
517 LOCK_TEST_WITH_RETURN(dev, file_priv); 536 RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
518 537
519 if (!dev_priv) { 538 if (!dev_priv) {
520 DRM_ERROR("called with no initialization\n"); 539 DRM_ERROR("called with no initialization\n");
521 return -EINVAL; 540 return -EINVAL;
522 } 541 }
523 542 mutex_lock(&dev->struct_mutex);
524 result = i915_emit_irq(dev); 543 result = i915_emit_irq(dev);
544 mutex_unlock(&dev->struct_mutex);
525 545
526 if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { 546 if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
527 DRM_ERROR("copy_to_user\n"); 547 DRM_ERROR("copy_to_user\n");