From: Sourab Gupta <[email protected]>

Adding the truncation logic for buffer objects with backing storage
from stolen memory. The objects will be truncated when user marks them
as purgeable and they are part of the inactive list.

Testcase: igt/gem_stolen_mem

Signed-off-by: Sourab Gupta <[email protected]>

Signed-off-by: Akash Goel <[email protected]>
Signed-off-by: Sourab Gupta <[email protected]>
---
 drivers/gpu/drm/i915/i915_drv.h        |    1 +
 drivers/gpu/drm/i915/i915_gem.c        |   11 ++++++++++-
 drivers/gpu/drm/i915/i915_gem_stolen.c |   32 ++++++++++++++++++++++++++++++++
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b5f603f..02142c0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2443,6 +2443,7 @@ i915_gem_object_create_stolen_for_preallocated(struct 
drm_device *dev,
                                               u32 size);
 void i915_gem_object_move_to_stolen(struct drm_i915_gem_object *obj);
 void i915_gem_object_release_stolen(struct drm_i915_gem_object *obj);
+void i915_gem_object_truncate_stolen(struct drm_i915_gem_object *obj);
 
 /* i915_gem_tiling.c */
 static inline bool i915_gem_object_needs_bit17_swizzle(struct 
drm_i915_gem_object *obj)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f57ca31..d106806 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2071,6 +2071,11 @@ i915_gem_object_move_to_inactive(struct 
drm_i915_gem_object *obj)
        obj->fenced_gpu_access = false;
 
        obj->active = 0;
+
+       /* Truncate the stolen obj immediately if it is marked as purgeable */
+       if(obj->stolen && (i915_gem_object_is_purgeable(obj) ) )
+               i915_gem_object_truncate_stolen(obj);
+
        drm_gem_object_unreference(&obj->base);
 
        WARN_ON(i915_verify_lists(dev));
@@ -4069,6 +4074,10 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void 
*data,
        if (i915_gem_object_is_purgeable(obj) && obj->pages == NULL)
                i915_gem_object_truncate(obj);
 
+       /* if the stolen mem object is no longer active, discard its backing 
storage */
+       if (obj->stolen && i915_gem_object_is_purgeable(obj) && 
i915_gem_object_is_inactive(obj))
+               i915_gem_object_truncate_stolen(obj);
+
        args->retained = obj->madv != __I915_MADV_PURGED;
 
 out:
@@ -4187,7 +4196,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
 
        /* Stolen objects don't hold a ref, but do hold pin count. Fix that up
         * before progressing. */
-       if (obj->stolen)
+       if ((obj->stolen) && (obj->madv != __I915_MADV_PURGED))
                i915_gem_object_unpin_pages(obj);
 
        if (WARN_ON(obj->pages_pin_count))
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 6758ba4..1ecc447 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -471,6 +471,11 @@ i915_gem_object_move_to_stolen(struct drm_i915_gem_object 
*obj)
        if (size == 0)
                return;
 
+       if (obj->madv != I915_MADV_WILLNEED) {
+               DRM_ERROR("Attempting to allocate a purgeable object\n");
+               return;
+       }
+
        /* Check if already shmem space has been allocated for the object
         * or not. We cannot rely upon on the value of 'pages' field for this.
         * As even though if the 'pages' field is NULL, it does not actually
@@ -549,3 +554,30 @@ i915_gem_object_release_stolen(struct drm_i915_gem_object 
*obj)
                obj->stolen = NULL;
        }
 }
+
+/*
+ * This function truncates stolen objects to reclaim their backing storage
+ * from stolen mem area. Currently objects are truncated when they are
+ * marked as purgeable and are in inactive list.
+ * Stolen objects are not considered for truncation by shrinker, as their
+ * physical pages are kept as pinned throughout their existance.
+ */
+void
+i915_gem_object_truncate_stolen(struct drm_i915_gem_object *obj)
+{
+       struct i915_vma *vma_temp,*next;
+
+       BUG_ON(!obj->stolen);
+
+       list_for_each_entry_safe(vma_temp, next, &obj->vma_list, vma_link)
+               WARN_ON(i915_vma_unbind(vma_temp));
+
+       i915_gem_object_unpin_pages(obj);
+       i915_gem_object_put_pages(obj);
+
+       /* Release the stolen space */
+       i915_gem_object_release_stolen(obj);
+
+       obj->madv = __I915_MADV_PURGED;
+
+}
-- 
1.7.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to