Skip to content

Commit

Permalink
drm/i915: Track purged state.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Chris Wilson committed Sep 23, 2009
1 parent 9731129 commit bb6baf7
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
24 changes: 15 additions & 9 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1470,6 +1470,7 @@ i915_gem_object_put_pages(struct drm_gem_object *obj)
int i;

BUG_ON(obj_priv->pages_refcount == 0);
BUG_ON(obj_priv->madv == __I915_MADV_PURGED);

if (--obj_priv->pages_refcount != 0)
return;
Expand Down Expand Up @@ -1534,11 +1535,14 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
static void
i915_gem_object_truncate(struct drm_gem_object *obj)
{
struct inode *inode;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
struct inode *inode;

inode = obj->filp->f_path.dentry->d_inode;
if (inode->i_op->truncate)
inode->i_op->truncate (inode);
inode = obj->filp->f_path.dentry->d_inode;
if (inode->i_op->truncate)
inode->i_op->truncate (inode);

obj_priv->madv = __I915_MADV_PURGED;
}

static inline int
Expand Down Expand Up @@ -2559,7 +2563,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
if (dev_priv->mm.suspended)
return -EBUSY;

if (obj_priv->madv == I915_MADV_DONTNEED) {
if (obj_priv->madv != I915_MADV_WILLNEED) {
DRM_ERROR("Attempting to bind a purgeable object\n");
return -EINVAL;
}
Expand Down Expand Up @@ -3928,8 +3932,8 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
}
obj_priv = obj->driver_private;

if (obj_priv->madv == I915_MADV_DONTNEED) {
DRM_ERROR("Attempting to pin a I915_MADV_DONTNEED buffer\n");
if (obj_priv->madv != I915_MADV_WILLNEED) {
DRM_ERROR("Attempting to pin a purgeable buffer\n");
drm_gem_object_unreference(obj);
mutex_unlock(&dev->struct_mutex);
return -EINVAL;
Expand Down Expand Up @@ -4081,14 +4085,16 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
return -EINVAL;
}

obj_priv->madv = args->madv;
args->retained = obj_priv->gtt_space != NULL;
if (obj_priv->madv != __I915_MADV_PURGED)
obj_priv->madv = args->madv;

/* if the object is no longer bound, discard its backing storage */
if (i915_gem_object_is_purgeable(obj_priv) &&
obj_priv->gtt_space == NULL)
i915_gem_object_truncate(obj);

args->retained = obj_priv->madv != __I915_MADV_PURGED;

drm_gem_object_unreference(obj);
mutex_unlock(&dev->struct_mutex);

Expand Down
1 change: 1 addition & 0 deletions include/drm/i915_drm.h
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ struct drm_i915_get_pipe_from_crtc_id {

#define I915_MADV_WILLNEED 0
#define I915_MADV_DONTNEED 1
#define __I915_MADV_PURGED 2 /* internal state */

struct drm_i915_gem_madvise {
/** Handle of the buffer to change the backing store advice */
Expand Down

0 comments on commit bb6baf7

Please sign in to comment.