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>

+16 -9
+15 -9
drivers/gpu/drm/i915/i915_gem.c
··· 1470 int i; 1471 1472 BUG_ON(obj_priv->pages_refcount == 0); 1473 1474 if (--obj_priv->pages_refcount != 0) 1475 return; ··· 1535 static void 1536 i915_gem_object_truncate(struct drm_gem_object *obj) 1537 { 1538 - struct inode *inode; 1539 1540 - inode = obj->filp->f_path.dentry->d_inode; 1541 - if (inode->i_op->truncate) 1542 - inode->i_op->truncate (inode); 1543 } 1544 1545 static inline int ··· 2563 if (dev_priv->mm.suspended) 2564 return -EBUSY; 2565 2566 - if (obj_priv->madv == I915_MADV_DONTNEED) { 2567 DRM_ERROR("Attempting to bind a purgeable object\n"); 2568 return -EINVAL; 2569 } ··· 3932 } 3933 obj_priv = obj->driver_private; 3934 3935 - if (obj_priv->madv == I915_MADV_DONTNEED) { 3936 - DRM_ERROR("Attempting to pin a I915_MADV_DONTNEED buffer\n"); 3937 drm_gem_object_unreference(obj); 3938 mutex_unlock(&dev->struct_mutex); 3939 return -EINVAL; ··· 4085 return -EINVAL; 4086 } 4087 4088 - obj_priv->madv = args->madv; 4089 - args->retained = obj_priv->gtt_space != NULL; 4090 4091 /* if the object is no longer bound, discard its backing storage */ 4092 if (i915_gem_object_is_purgeable(obj_priv) && 4093 obj_priv->gtt_space == NULL) 4094 i915_gem_object_truncate(obj); 4095 4096 drm_gem_object_unreference(obj); 4097 mutex_unlock(&dev->struct_mutex);
··· 1470 int i; 1471 1472 BUG_ON(obj_priv->pages_refcount == 0); 1473 + BUG_ON(obj_priv->madv == __I915_MADV_PURGED); 1474 1475 if (--obj_priv->pages_refcount != 0) 1476 return; ··· 1534 static void 1535 i915_gem_object_truncate(struct drm_gem_object *obj) 1536 { 1537 + struct drm_i915_gem_object *obj_priv = obj->driver_private; 1538 + struct inode *inode; 1539 1540 + inode = obj->filp->f_path.dentry->d_inode; 1541 + if (inode->i_op->truncate) 1542 + inode->i_op->truncate (inode); 1543 + 1544 + obj_priv->madv = __I915_MADV_PURGED; 1545 } 1546 1547 static inline int ··· 2559 if (dev_priv->mm.suspended) 2560 return -EBUSY; 2561 2562 + if (obj_priv->madv != I915_MADV_WILLNEED) { 2563 DRM_ERROR("Attempting to bind a purgeable object\n"); 2564 return -EINVAL; 2565 } ··· 3928 } 3929 obj_priv = obj->driver_private; 3930 3931 + if (obj_priv->madv != I915_MADV_WILLNEED) { 3932 + DRM_ERROR("Attempting to pin a purgeable buffer\n"); 3933 drm_gem_object_unreference(obj); 3934 mutex_unlock(&dev->struct_mutex); 3935 return -EINVAL; ··· 4081 return -EINVAL; 4082 } 4083 4084 + if (obj_priv->madv != __I915_MADV_PURGED) 4085 + obj_priv->madv = args->madv; 4086 4087 /* if the object is no longer bound, discard its backing storage */ 4088 if (i915_gem_object_is_purgeable(obj_priv) && 4089 obj_priv->gtt_space == NULL) 4090 i915_gem_object_truncate(obj); 4091 + 4092 + args->retained = obj_priv->madv != __I915_MADV_PURGED; 4093 4094 drm_gem_object_unreference(obj); 4095 mutex_unlock(&dev->struct_mutex);
+1
include/drm/i915_drm.h
··· 671 672 #define I915_MADV_WILLNEED 0 673 #define I915_MADV_DONTNEED 1 674 675 struct drm_i915_gem_madvise { 676 /** Handle of the buffer to change the backing store advice */
··· 671 672 #define I915_MADV_WILLNEED 0 673 #define I915_MADV_DONTNEED 1 674 + #define __I915_MADV_PURGED 2 /* internal state */ 675 676 struct drm_i915_gem_madvise { 677 /** Handle of the buffer to change the backing store advice */