aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2039-drm-ttm-fix-busy-memory-to-fail-other-user-v10.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2039-drm-ttm-fix-busy-memory-to-fail-other-user-v10.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2039-drm-ttm-fix-busy-memory-to-fail-other-user-v10.patch173
1 files changed, 173 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2039-drm-ttm-fix-busy-memory-to-fail-other-user-v10.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2039-drm-ttm-fix-busy-memory-to-fail-other-user-v10.patch
new file mode 100644
index 00000000..5a620a2e
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2039-drm-ttm-fix-busy-memory-to-fail-other-user-v10.patch
@@ -0,0 +1,173 @@
+From 0d738510e75bcf8974def92502d4a557c80d33fc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Wed, 22 May 2019 09:51:47 +0200
+Subject: [PATCH 2039/2940] drm/ttm: fix busy memory to fail other user v10
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BOs on the LRU might be blocked during command submission
+and cause OOM situations.
+
+Avoid this by blocking for the first busy BO not locked by
+the same ticket as the BO we are searching space for.
+
+v10: completely start over with the patch since we didn't
+ handled a whole bunch of corner cases.
+
+Change-Id: I65309984703ef5acc83ef0bfa7c35ad24150fe9d
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
+Tested-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
+Signed-off-by: Chaudhary Amit Kumar <Chaudharyamit.Kumar@amd.com>
+---
+ drivers/gpu/drm/ttm/ttm_bo.c | 77 +++++++++++++++++++++++++++++++-----
+ 1 file changed, 67 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
+index 0afa619c49ab..40b4b1bcd258 100644
+--- a/drivers/gpu/drm/ttm/ttm_bo.c
++++ b/drivers/gpu/drm/ttm/ttm_bo.c
+@@ -779,7 +779,7 @@ EXPORT_SYMBOL(ttm_bo_eviction_valuable);
+ * b. Otherwise, trylock it.
+ */
+ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
+- struct ttm_operation_ctx *ctx, bool *locked)
++ struct ttm_operation_ctx *ctx, bool *locked, bool *busy)
+ {
+ bool ret = false;
+
+@@ -789,22 +789,64 @@ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
+ if (ctx->flags & TTM_OPT_FLAG_ALLOW_RES_EVICT
+ || !list_empty(&bo->ddestroy))
+ ret = true;
++ *locked = false;
++ if (busy)
++ *busy = false;
+ } else {
+- *locked = reservation_object_trylock(bo->resv);
+- ret = *locked;
++ ret = reservation_object_trylock(bo->resv);
++ *locked = ret;
++ if (busy)
++ *busy = !ret;
+ }
+
+ return ret;
+ }
+
++/**
++ * ttm_mem_evict_wait_busy - wait for a busy BO to become available
++ *
++ * @busy_bo: BO which couldn't be locked with trylock
++ * @ctx: operation context
++ * @ticket: acquire ticket
++ *
++ * Try to lock a busy buffer object to avoid failing eviction.
++ */
++static int ttm_mem_evict_wait_busy(struct ttm_buffer_object *busy_bo,
++ struct ttm_operation_ctx *ctx,
++ struct ww_acquire_ctx *ticket)
++{
++ int r;
++
++ if (!busy_bo || !ticket)
++ return -EBUSY;
++
++ if (ctx->interruptible)
++ r = reservation_object_lock_interruptible(busy_bo->resv,
++ ticket);
++ else
++ r = reservation_object_lock(busy_bo->resv, ticket);
++
++ /*
++ * TODO: It would be better to keep the BO locked until allocation is at
++ * least tried one more time, but that would mean a much larger rework
++ * of TTM.
++ */
++ if (!r)
++ reservation_object_unlock(busy_bo->resv);
++
++ return r == -EDEADLK ? -EAGAIN : r;
++}
++
++
+ static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
+ uint32_t mem_type,
+ const struct ttm_place *place,
+- struct ttm_operation_ctx *ctx)
++ struct ttm_operation_ctx *ctx,
++ struct ww_acquire_ctx *ticket)
+ {
++ struct ttm_buffer_object *bo = NULL, *busy_bo = NULL;
+ struct ttm_bo_global *glob = bdev->glob;
+ struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+- struct ttm_buffer_object *bo = NULL;
+ bool locked = false;
+ unsigned i;
+ int ret;
+@@ -812,8 +854,15 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
+ spin_lock(&glob->lru_lock);
+ for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
+ list_for_each_entry(bo, &man->lru[i], lru) {
+- if (!ttm_bo_evict_swapout_allowable(bo, ctx, &locked))
++ bool busy;
++
++ if (!ttm_bo_evict_swapout_allowable(bo, ctx, &locked,
++ &busy)) {
++ if (busy && !busy_bo &&
++ bo->resv->lock.ctx != ticket)
++ busy_bo = bo;
+ continue;
++ }
+
+ if (place && !bdev->driver->eviction_valuable(bo,
+ place)) {
+@@ -832,8 +881,13 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
+ }
+
+ if (!bo) {
++ if (busy_bo)
++ ttm_bo_get(busy_bo);
+ spin_unlock(&glob->lru_lock);
+- return -EBUSY;
++ ret = ttm_mem_evict_wait_busy(busy_bo, ctx, ticket);
++ if (busy_bo)
++ ttm_bo_put(busy_bo);
++ return ret;
+ }
+
+ kref_get(&bo->list_kref);
+@@ -917,7 +971,8 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
+ return ret;
+ if (mem->mm_node)
+ break;
+- ret = ttm_mem_evict_first(bdev, mem->mem_type, place, ctx);
++ ret = ttm_mem_evict_first(bdev, mem->mem_type, place, ctx,
++ bo->resv->lock.ctx);
+ if (unlikely(ret != 0))
+ return ret;
+ } while (1);
+@@ -1416,7 +1471,8 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
+ for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
+ while (!list_empty(&man->lru[i])) {
+ spin_unlock(&glob->lru_lock);
+- ret = ttm_mem_evict_first(bdev, mem_type, NULL, &ctx);
++ ret = ttm_mem_evict_first(bdev, mem_type, NULL, &ctx,
++ NULL);
+ if (ret)
+ return ret;
+ spin_lock(&glob->lru_lock);
+@@ -1771,7 +1827,8 @@ int ttm_bo_swapout(struct ttm_bo_global *glob, struct ttm_operation_ctx *ctx)
+ spin_lock(&glob->lru_lock);
+ for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
+ list_for_each_entry(bo, &glob->swap_lru[i], swap) {
+- if (ttm_bo_evict_swapout_allowable(bo, ctx, &locked)) {
++ if (ttm_bo_evict_swapout_allowable(bo, ctx, &locked,
++ NULL)) {
+ ret = 0;
+ break;
+ }
+--
+2.17.1
+