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