diff options
author | Keith Packard <keithp@keithp.com> | 2008-06-13 19:40:16 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2008-06-13 19:40:16 -0700 |
commit | 68856b619bc1a2e91e67764911c8af4e2466fad9 (patch) | |
tree | 917f46f883e2fb76c85b532343a30e4da8a22d43 | |
parent | 732b1960742042eb33f49c2b3cdd2d36eadbc920 (diff) |
[intel-gem] Debugging -- verify inactive list invariants
Inactive list elements may not be pinned, active or have non-CPU write
domains.
-rw-r--r-- | linux-core/i915_gem.c | 40 |
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 |