aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-09-22 09:24:13 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2009-09-22 20:10:38 -0400
commitbb6baf76f45708dbba651ed76a7ad94462f30c0b (patch)
treea58c54d10d9f35f32799d59189467607a84c1b4c /drivers/gpu
parent9731129c5e3077d0c2da13479f91c3a07e341f70 (diff)
drm/i915: Track purged state.
In order to correctly prevent the invalid reuse of a purged buffer, we need to track such events and warn the user before something bad happens. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 8beec97fa348..f4f714e39b7b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1470,6 +1470,7 @@ i915_gem_object_put_pages(struct drm_gem_object *obj)
1470 int i; 1470 int i;
1471 1471
1472 BUG_ON(obj_priv->pages_refcount == 0); 1472 BUG_ON(obj_priv->pages_refcount == 0);
1473 BUG_ON(obj_priv->madv == __I915_MADV_PURGED);
1473 1474
1474 if (--obj_priv->pages_refcount != 0) 1475 if (--obj_priv->pages_refcount != 0)
1475 return; 1476 return;
@@ -1534,11 +1535,14 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
1534static void 1535static void
1535i915_gem_object_truncate(struct drm_gem_object *obj) 1536i915_gem_object_truncate(struct drm_gem_object *obj)
1536{ 1537{
1537 struct inode *inode; 1538 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1539 struct inode *inode;
1538 1540
1539 inode = obj->filp->f_path.dentry->d_inode; 1541 inode = obj->filp->f_path.dentry->d_inode;
1540 if (inode->i_op->truncate) 1542 if (inode->i_op->truncate)
1541 inode->i_op->truncate (inode); 1543 inode->i_op->truncate (inode);
1544
1545 obj_priv->madv = __I915_MADV_PURGED;
1542} 1546}
1543 1547
1544static inline int 1548static inline int
@@ -2559,7 +2563,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2559 if (dev_priv->mm.suspended) 2563 if (dev_priv->mm.suspended)
2560 return -EBUSY; 2564 return -EBUSY;
2561 2565
2562 if (obj_priv->madv == I915_MADV_DONTNEED) { 2566 if (obj_priv->madv != I915_MADV_WILLNEED) {
2563 DRM_ERROR("Attempting to bind a purgeable object\n"); 2567 DRM_ERROR("Attempting to bind a purgeable object\n");
2564 return -EINVAL; 2568 return -EINVAL;
2565 } 2569 }
@@ -3928,8 +3932,8 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
3928 } 3932 }
3929 obj_priv = obj->driver_private; 3933 obj_priv = obj->driver_private;
3930 3934
3931 if (obj_priv->madv == I915_MADV_DONTNEED) { 3935 if (obj_priv->madv != I915_MADV_WILLNEED) {
3932 DRM_ERROR("Attempting to pin a I915_MADV_DONTNEED buffer\n"); 3936 DRM_ERROR("Attempting to pin a purgeable buffer\n");
3933 drm_gem_object_unreference(obj); 3937 drm_gem_object_unreference(obj);
3934 mutex_unlock(&dev->struct_mutex); 3938 mutex_unlock(&dev->struct_mutex);
3935 return -EINVAL; 3939 return -EINVAL;
@@ -4081,14 +4085,16 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
4081 return -EINVAL; 4085 return -EINVAL;
4082 } 4086 }
4083 4087
4084 obj_priv->madv = args->madv; 4088 if (obj_priv->madv != __I915_MADV_PURGED)
4085 args->retained = obj_priv->gtt_space != NULL; 4089 obj_priv->madv = args->madv;
4086 4090
4087 /* if the object is no longer bound, discard its backing storage */ 4091 /* if the object is no longer bound, discard its backing storage */
4088 if (i915_gem_object_is_purgeable(obj_priv) && 4092 if (i915_gem_object_is_purgeable(obj_priv) &&
4089 obj_priv->gtt_space == NULL) 4093 obj_priv->gtt_space == NULL)
4090 i915_gem_object_truncate(obj); 4094 i915_gem_object_truncate(obj);
4091 4095
4096 args->retained = obj_priv->madv != __I915_MADV_PURGED;
4097
4092 drm_gem_object_unreference(obj); 4098 drm_gem_object_unreference(obj);
4093 mutex_unlock(&dev->struct_mutex); 4099 mutex_unlock(&dev->struct_mutex);
4094 4100