diff options
| author | Tvrtko Ursulin <tvrtko.ursulin@intel.com> | 2014-09-26 10:05:22 -0400 |
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-09-29 09:31:01 -0400 |
| commit | c479f4383ea8940dd6f88da61798ad31feb33e51 (patch) | |
| tree | 0904e286cbbf9d300385f4714584ab3d8bb4e180 /drivers/gpu | |
| parent | e9681366ea9e76ab8f75e84351f2f3ca63ee542c (diff) | |
drm/i915: Do not leak pages when freeing userptr objects
sg_alloc_table_from_pages() can build us a table with coalesced ranges which
means we need to iterate over pages and not sg table entries when releasing
page references.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: "Barbalho, Rafael" <rafael.barbalho@intel.com>
Tested-by: Rafael Barbalho <rafael.barbalho@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: stable@vger.kernel.org
[danvet: Remove unused local variable sg.]
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_userptr.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index f5efbb836e5c..d182058383a9 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c | |||
| @@ -689,16 +689,15 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) | |||
| 689 | static void | 689 | static void |
| 690 | i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj) | 690 | i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj) |
| 691 | { | 691 | { |
| 692 | struct scatterlist *sg; | 692 | struct sg_page_iter sg_iter; |
| 693 | int i; | ||
| 694 | 693 | ||
| 695 | BUG_ON(obj->userptr.work != NULL); | 694 | BUG_ON(obj->userptr.work != NULL); |
| 696 | 695 | ||
| 697 | if (obj->madv != I915_MADV_WILLNEED) | 696 | if (obj->madv != I915_MADV_WILLNEED) |
| 698 | obj->dirty = 0; | 697 | obj->dirty = 0; |
| 699 | 698 | ||
| 700 | for_each_sg(obj->pages->sgl, sg, obj->pages->nents, i) { | 699 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) { |
| 701 | struct page *page = sg_page(sg); | 700 | struct page *page = sg_page_iter_page(&sg_iter); |
| 702 | 701 | ||
| 703 | if (obj->dirty) | 702 | if (obj->dirty) |
| 704 | set_page_dirty(page); | 703 | set_page_dirty(page); |
