Commit 004746e4 authored by Thomas Hellström's avatar Thomas Hellström

drm/i915/ttm: Correctly handle waiting for gpu when shrinking

With async migration, the shrinker may end up wanting to release the
pages of an object while the migration blit is still running, since
the GT migration code doesn't set up VMAs and the shrinker is thus
oblivious to the fact that the GPU is still using the pages.

Add waiting for gpu in the shrinker_release_pages() op and an
argument to that function indicating whether the shrinker expects it
to not wait for gpu. In the latter case the shrinker_release_pages()
op will return -EBUSY if the object is not idle.
Signed-off-by: default avatarThomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211122214554.371864-5-thomas.hellstrom@linux.intel.com
parent 8b1f7f92
...@@ -59,6 +59,7 @@ struct drm_i915_gem_object_ops { ...@@ -59,6 +59,7 @@ struct drm_i915_gem_object_ops {
int (*truncate)(struct drm_i915_gem_object *obj); int (*truncate)(struct drm_i915_gem_object *obj);
void (*writeback)(struct drm_i915_gem_object *obj); void (*writeback)(struct drm_i915_gem_object *obj);
int (*shrinker_release_pages)(struct drm_i915_gem_object *obj, int (*shrinker_release_pages)(struct drm_i915_gem_object *obj,
bool no_gpu_wait,
bool should_writeback); bool should_writeback);
int (*pread)(struct drm_i915_gem_object *obj, int (*pread)(struct drm_i915_gem_object *obj,
......
...@@ -60,6 +60,7 @@ static int try_to_writeback(struct drm_i915_gem_object *obj, unsigned int flags) ...@@ -60,6 +60,7 @@ static int try_to_writeback(struct drm_i915_gem_object *obj, unsigned int flags)
{ {
if (obj->ops->shrinker_release_pages) if (obj->ops->shrinker_release_pages)
return obj->ops->shrinker_release_pages(obj, return obj->ops->shrinker_release_pages(obj,
!(flags & I915_SHRINK_ACTIVE),
flags & I915_SHRINK_WRITEBACK); flags & I915_SHRINK_WRITEBACK);
switch (obj->mm.madv) { switch (obj->mm.madv) {
......
...@@ -418,6 +418,7 @@ int i915_ttm_purge(struct drm_i915_gem_object *obj) ...@@ -418,6 +418,7 @@ int i915_ttm_purge(struct drm_i915_gem_object *obj)
} }
static int i915_ttm_shrinker_release_pages(struct drm_i915_gem_object *obj, static int i915_ttm_shrinker_release_pages(struct drm_i915_gem_object *obj,
bool no_wait_gpu,
bool should_writeback) bool should_writeback)
{ {
struct ttm_buffer_object *bo = i915_gem_to_ttm(obj); struct ttm_buffer_object *bo = i915_gem_to_ttm(obj);
...@@ -425,7 +426,7 @@ static int i915_ttm_shrinker_release_pages(struct drm_i915_gem_object *obj, ...@@ -425,7 +426,7 @@ static int i915_ttm_shrinker_release_pages(struct drm_i915_gem_object *obj,
container_of(bo->ttm, typeof(*i915_tt), ttm); container_of(bo->ttm, typeof(*i915_tt), ttm);
struct ttm_operation_ctx ctx = { struct ttm_operation_ctx ctx = {
.interruptible = true, .interruptible = true,
.no_wait_gpu = false, .no_wait_gpu = no_wait_gpu,
}; };
struct ttm_placement place = {}; struct ttm_placement place = {};
int ret; int ret;
...@@ -438,6 +439,10 @@ static int i915_ttm_shrinker_release_pages(struct drm_i915_gem_object *obj, ...@@ -438,6 +439,10 @@ static int i915_ttm_shrinker_release_pages(struct drm_i915_gem_object *obj,
if (!i915_tt->filp) if (!i915_tt->filp)
return 0; return 0;
ret = ttm_bo_wait_ctx(bo, &ctx);
if (ret)
return ret;
switch (obj->mm.madv) { switch (obj->mm.madv) {
case I915_MADV_DONTNEED: case I915_MADV_DONTNEED:
return i915_ttm_purge(obj); return i915_ttm_purge(obj);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment