summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-06-13 19:40:16 -0700
committerKeith Packard <keithp@keithp.com>2008-06-13 19:40:16 -0700
commit68856b619bc1a2e91e67764911c8af4e2466fad9 (patch)
tree917f46f883e2fb76c85b532343a30e4da8a22d43 /linux-core
parent732b1960742042eb33f49c2b3cdd2d36eadbc920 (diff)
[intel-gem] Debugging -- verify inactive list invariants
Inactive list elements may not be pinned, active or have non-CPU write domains.
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/i915_gem.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c
index 78d0d952..8741eecd 100644
--- a/linux-core/i915_gem.c
+++ b/linux-core/i915_gem.c
@@ -35,6 +35,7 @@
#define WATCH_EXEC 0
#define WATCH_LRU 0
#define WATCH_RELOC 0
+#define WATCH_INACTIVE 0
static int
i915_gem_object_set_domain(struct drm_gem_object *obj,
@@ -303,6 +304,26 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj)
&dev_priv->mm.active_list);
}
+#if WATCH_INACTIVE
+static void
+i915_verify_inactive(struct drm_device *dev, char *file, int line)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+
+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
+ obj = obj_priv->obj;
+ if (obj_priv->pin_count || obj_priv->active || (obj->write_domain & ~I915_GEM_DOMAIN_CPU))
+ DRM_ERROR("inactive %p (p %d a %d w %x) %s:%d\n",
+ obj,
+ obj_priv->pin_count, obj_priv->active, obj->write_domain, file, line);
+ }
+}
+#else
+#define i915_verify_inactive(dev,file,line)
+#endif
+
static void
i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
{
@@ -310,6 +331,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ i915_verify_inactive(dev, __FILE__, __LINE__);
if (obj_priv->pin_count != 0)
list_del_init(&obj_priv->list);
else
@@ -319,6 +341,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
obj_priv->active = 0;
drm_gem_object_unreference(obj);
}
+ i915_verify_inactive(dev, __FILE__, __LINE__);
}
/**
@@ -1635,6 +1658,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
mutex_lock(&dev->struct_mutex);
+ i915_verify_inactive(dev, __FILE__, __LINE__);
if (dev_priv->mm.suspended) {
DRM_ERROR("Execbuf while VT-switched.\n");
mutex_unlock(&dev->struct_mutex);
@@ -1676,6 +1700,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
batch_obj->pending_read_domains = I915_GEM_DOMAIN_COMMAND;
batch_obj->pending_write_domain = 0;
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+
for (i = 0; i < args->buffer_count; i++) {
struct drm_gem_object *obj = object_list[i];
struct drm_i915_gem_object *obj_priv = obj->driver_private;
@@ -1698,9 +1724,13 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
goto err;
}
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+
/* Flush/invalidate caches and chipset buffer */
flush_domains = i915_gem_dev_set_domain(dev);
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+
#if WATCH_COHERENCY
for (i = 0; i < args->buffer_count; i++) {
i915_gem_object_check_coherency(object_list[i],
@@ -1730,6 +1760,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
*/
flush_domains |= i915_retire_commands(dev);
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+
/*
* Get a seqno representing the execution of the current buffer,
* which we can wait on. We would like to mitigate these interrupts,
@@ -1754,6 +1786,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
i915_dump_lru(dev, __func__);
#endif
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+
/* Copy the new buffer offsets back to the user's exec list. */
ret = copy_to_user((struct drm_i915_relocation_entry __user *)
(uintptr_t) args->buffers_ptr,
@@ -1789,6 +1823,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
struct drm_i915_gem_object *obj_priv = obj->driver_private;
int ret;
+ i915_verify_inactive(dev, __FILE__, __LINE__);
if (obj_priv->gtt_space == NULL) {
ret = i915_gem_object_bind_to_gtt(obj, alignment);
if (ret != 0) {
@@ -1807,6 +1842,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
if (!obj_priv->active && obj->write_domain == 0)
list_del_init(&obj_priv->list);
}
+ i915_verify_inactive(dev, __FILE__, __LINE__);
return 0;
}
@@ -1818,10 +1854,11 @@ i915_gem_object_unpin(struct drm_gem_object *obj)
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ i915_verify_inactive(dev, __FILE__, __LINE__);
obj_priv->pin_count--;
BUG_ON(obj_priv->pin_count < 0);
BUG_ON(obj_priv->gtt_space == NULL);
-
+
/* If the object is no longer pinned, and is
* neither active nor being flushed, then stick it on
* the inactive list
@@ -1832,6 +1869,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj)
atomic_dec(&dev->pin_count);
atomic_sub(obj->size, &dev->pin_memory);
}
+ i915_verify_inactive(dev, __FILE__, __LINE__);
}
int