summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2013-03-28 22:41:49 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2013-03-28 22:41:49 +0000
commit8eab78c8852faa4c8235857c862c11335c196128 (patch)
tree79062b3b75e811fc9b7f0995b37a571e10af067d /sys/dev/pci
parent3e8bac15baa10a06bc360d6764b4fd7444b063b4 (diff)
Add missing locking in i915_gem_retire_work_handler() and call
intel_mark_idle() when idle.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/drm/i915/i915_gem.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/sys/dev/pci/drm/i915/i915_gem.c b/sys/dev/pci/drm/i915/i915_gem.c
index 8529acdd421..cb6a18a7fee 100644
--- a/sys/dev/pci/drm/i915/i915_gem.c
+++ b/sys/dev/pci/drm/i915/i915_gem.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i915_gem.c,v 1.6 2013/03/28 19:38:53 kettenis Exp $ */
+/* $OpenBSD: i915_gem.c,v 1.7 2013/03/28 22:41:48 kettenis Exp $ */
/*
* Copyright (c) 2008-2009 Owain G. Ainsworth <oga@openbsd.org>
*
@@ -1525,12 +1525,25 @@ i915_gem_retire_requests(struct inteldrm_softc *dev_priv)
void
i915_gem_retire_work_handler(void *arg1, void *unused)
{
- struct inteldrm_softc *dev_priv = arg1;
+ struct inteldrm_softc *dev_priv = arg1;
+ struct drm_device *dev;
struct intel_ring_buffer *ring;
- bool idle;
- int i;
+ bool idle;
+ int i;
+
+ dev = (struct drm_device *)dev_priv->drmdev;
+
+ /* Come back later if the device is busy... */
+ if (rw_enter(&dev->dev_lock, RW_NOSLEEP | RW_WRITE)) {
+ timeout_add_sec(&dev_priv->mm.retire_timer, 1);
+ return;
+ }
i915_gem_retire_requests(dev_priv);
+
+ /* Send a periodic flush down the ring so we don't hold onto GEM
+ * objects indefinitely.
+ */
idle = true;
for_each_ring(ring, dev_priv, i) {
if (ring->gpu_caches_dirty)
@@ -1540,6 +1553,10 @@ i915_gem_retire_work_handler(void *arg1, void *unused)
}
if (!dev_priv->mm.suspended && !idle)
timeout_add_sec(&dev_priv->mm.retire_timer, 1);
+ if (idle)
+ intel_mark_idle(dev);
+
+ DRM_UNLOCK();
}
/**