diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-09-04 21:02:54 +0100 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-09-20 14:22:56 +0200 |
commit | a5570178c059cec59e9835be20bc8546377fa7b5 (patch) | |
tree | 02689b01aa2d069ec59cbc7b1f95af61a1003d31 /drivers/gpu/drm/i915/i915_gem.c | |
parent | 37e680a15ff6375ff02773161f817e90a38c51f7 (diff) | |
download | lwn-a5570178c059cec59e9835be20bc8546377fa7b5.tar.gz lwn-a5570178c059cec59e9835be20bc8546377fa7b5.zip |
drm/i915: Pin backing pages whilst exporting through a dmabuf vmap
We need to refcount our pages in order to prevent reaping them at
inopportune times, such as when they currently vmapped or exported to
another driver. However, we also wish to keep the lazy deallocation of
our pages so we need to take a pin/unpinned approach rather than a
simple refcount.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4b2ee7ce8b15..ea3a5e1791e9 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1699,6 +1699,9 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj) BUG_ON(obj->gtt_space); + if (obj->pages_pin_count) + return -EBUSY; + ops->put_pages(obj); list_del(&obj->gtt_list); @@ -1837,6 +1840,8 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj) if (obj->sg_table || obj->pages) return 0; + BUG_ON(obj->pages_pin_count); + ret = ops->get_pages(obj); if (ret) return ret; @@ -3743,6 +3748,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) dev_priv->mm.interruptible = was_interruptible; } + obj->pages_pin_count = 0; i915_gem_object_put_pages(obj); i915_gem_object_free_mmap_offset(obj); @@ -4402,9 +4408,10 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) cnt = 0; list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list) - cnt += obj->base.size >> PAGE_SHIFT; + if (obj->pages_pin_count == 0) + cnt += obj->base.size >> PAGE_SHIFT; list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) - if (obj->pin_count == 0) + if (obj->pin_count == 0 && obj->pages_pin_count == 0) cnt += obj->base.size >> PAGE_SHIFT; mutex_unlock(&dev->struct_mutex); |