summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-06-06 12:59:52 -0700
committerKeith Packard <keithp@keithp.com>2008-06-06 13:00:47 -0700
commit9f46c6935d154743162c6239903a4a9e443907bc (patch)
tree8212464335d194a7c1f909d2eb20523fbcd6b789 /shared-core
parenta708106c77f74f146722fba35eae772fb554ee9a (diff)
[intel-gem] Use timers to retire requests periodically.
Without the user IRQ running constantly, there's no wakeup when the ring empties to go retire requests and free buffers. Use a 1 second timer to make that happen more often.
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/i915_dma.c5
-rw-r--r--shared-core/i915_drv.h12
2 files changed, 17 insertions, 0 deletions
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c
index c0ddeae0..f6465bf6 100644
--- a/shared-core/i915_dma.c
+++ b/shared-core/i915_dma.c
@@ -1078,6 +1078,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
INIT_LIST_HEAD(&dev_priv->mm.request_list);
+ dev_priv->mm.retire_timer.function = i915_gem_retire_timeout;
+ dev_priv->mm.retire_timer.data = (unsigned long) dev;
+ init_timer_deferrable (&dev_priv->mm.retire_timer);
+ INIT_WORK(&dev_priv->mm.retire_task,
+ i915_gem_retire_handler);
INIT_WORK(&dev_priv->user_interrupt_task,
i915_user_interrupt_handler);
dev_priv->mm.next_gem_seqno = 1;
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index 33fb7ca9..55af6552 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -280,6 +280,16 @@ typedef struct drm_i915_private {
*/
struct list_head request_list;
+ /**
+ * We leave the user IRQ off as much as possible,
+ * but this means that requests will finish and never
+ * be retired once the system goes idle. Set a timer to
+ * fire periodically while the ring is running. When it
+ * fires, go retire requests.
+ */
+ struct timer_list retire_timer;
+ struct work_struct retire_task;
+
uint32_t next_gem_seqno;
} mm;
@@ -463,6 +473,8 @@ int i915_gem_flush_pwrite(struct drm_gem_object *obj,
uint64_t offset, uint64_t size);
void i915_gem_lastclose(struct drm_device *dev);
void i915_gem_retire_requests(struct drm_device *dev);
+void i915_gem_retire_timeout(unsigned long data);
+void i915_gem_retire_handler(struct work_struct *work);
#endif
#ifdef __linux__