[PATCH 4.10 06/29] drm/i915: Store a permanent error in obj->mm.pages

From: Greg Kroah-Hartman
Date: Sun Apr 16 2017 - 04:08:23 EST


4.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>

commit 0d9dc306e15b59bf50db87ebcb1e2248586d4733 upstream.

Once the object has been truncated, it is unrecoverable. To facilitate
detection of this state store the error in obj->mm.pages.

This is required for the next patch which should be applied to v4.10
(via stable), so we also need to mark this patch for backporting. In
that regard, let's consider this to be a fix/improvement too.

v2: Avoid dereferencing the ERR_PTR when freeing the object.

Fixes: 1233e2db199d ("drm/i915: Move object backing storage manipulation to its own locking")
Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx>
Link: http://patchwork.freedesktop.org/patch/msgid/20170307132031.32461-1-chris@xxxxxxxxxxxxxxxxxx
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx>
(cherry picked from commit 4e5462ee843c883790e9609cf560d88960ea4227)
Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
drivers/gpu/drm/i915/i915_gem.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2184,6 +2184,7 @@ i915_gem_object_truncate(struct drm_i915
*/
shmem_truncate_range(file_inode(obj->base.filp), 0, (loff_t)-1);
obj->mm.madv = __I915_MADV_PURGED;
+ obj->mm.pages = ERR_PTR(-EFAULT);
}

/* Try to discard unwanted pages */
@@ -2283,7 +2284,9 @@ void __i915_gem_object_put_pages(struct

__i915_gem_object_reset_page_iter(obj);

- obj->ops->put_pages(obj, pages);
+ if (!IS_ERR(pages))
+ obj->ops->put_pages(obj, pages);
+
unlock:
mutex_unlock(&obj->mm.lock);
}
@@ -2501,7 +2504,7 @@ int __i915_gem_object_get_pages(struct d
if (err)
return err;

- if (unlikely(!obj->mm.pages)) {
+ if (unlikely(IS_ERR_OR_NULL(obj->mm.pages))) {
err = ____i915_gem_object_get_pages(obj);
if (err)
goto unlock;
@@ -2579,7 +2582,7 @@ void *i915_gem_object_pin_map(struct drm

pinned = true;
if (!atomic_inc_not_zero(&obj->mm.pages_pin_count)) {
- if (unlikely(!obj->mm.pages)) {
+ if (unlikely(IS_ERR_OR_NULL(obj->mm.pages))) {
ret = ____i915_gem_object_get_pages(obj);
if (ret)
goto err_unlock;