[10/11] drm/ttm: some good fixes for per-vm-lru

Submitted by Zhou, David(ChunMing) on April 12, 2018, 10:09 a.m.

Details

Message ID 20180412100940.25039-11-david1.zhou@amd.com
State New
Headers show
Series "***[WIP] TTM per process lru ***" ( rev: 1 ) in AMD X.Org drivers

Not browsing as part of any series.

Commit Message

Zhou, David(ChunMing) April 12, 2018, 10:09 a.m.
Change-Id: Ib68bff91fd127162cf8c72516101546e1fe014df
Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c |  1 -
 drivers/gpu/drm/ttm/ttm_bo.c               | 39 ++++++++++++++++++++----------
 2 files changed, 26 insertions(+), 14 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index d54abba4e017..ea95c2e9a858 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -625,7 +625,6 @@  static int amdgpu_bo_do_create1(struct amdgpu_device *adev, unsigned long size,
 	bo->tbo.index = (u64)atomic64_inc_return(&process->bo_index);
 
 	bo->tbo.bdev = &adev->mman.bdev;
-	RB_CLEAR_NODE(&bo->tbo.node);
 	amdgpu_ttm_placement_from_domain(bo, domains);
 	r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type,
 				 &bo->placement, page_align, &ctx, acc_size,
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index d56312702b49..dc9545eeb5d6 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -164,15 +164,12 @@  static void ttm_bo_add_to_rb(struct ttm_buffer_object *bo,
         while (*new) {
 		struct ttm_buffer_object *this =
 			container_of(*new, struct ttm_buffer_object, node);
-		int result = bo->index - this->index;
 
 		parent = *new;
-		if (result < 0)
+		if (bo->index < this->index)
 			new = &((*new)->rb_left);
-		else if (result > 0)
-			new = &((*new)->rb_right);
 		else
-			return;
+			new = &((*new)->rb_right);
 	}
 	rb_link_node(&bo->node, parent, new);
 	rb_insert_color(&bo->node, root);
@@ -211,6 +208,24 @@  static void ttm_bo_ref_bug(struct kref *list_kref)
 	BUG();
 }
 
+static struct ttm_buffer_object *ttm_bo_rb_find(struct rb_root *root, u64 index)
+{
+	struct rb_node *node = root->rb_node;
+
+	while (node) {
+		struct ttm_buffer_object *bo =
+			container_of(node, struct ttm_buffer_object, node);
+
+		if (index < bo->index)
+			node = node->rb_left;
+		else if (index > bo->index)
+			node = node->rb_right;
+		else
+			return bo;
+	}
+
+	return NULL;
+}
 void ttm_bo_del_from_lru(struct ttm_buffer_object *bo)
 {
 	if (!list_empty(&bo->swap)) {
@@ -220,10 +235,10 @@  void ttm_bo_del_from_lru(struct ttm_buffer_object *bo)
 	if (!list_empty(&bo->lru)) {
 		list_del_init(&bo->lru);
 		kref_put(&bo->list_kref, ttm_bo_ref_bug);
-	} else if (RB_EMPTY_NODE(&bo->node)) {
+	} else if
+		(ttm_bo_rb_find(&bo->process->fixed_lru[bo->mem.mem_type][bo->priority], bo->index)) {
 		rb_erase(&bo->node,
 			 &bo->process->fixed_lru[bo->mem.mem_type][bo->priority]);
-		RB_CLEAR_NODE(&bo->node);
 		kref_put(&bo->list_kref, ttm_bo_ref_bug);
 	}
 	/*
@@ -769,23 +784,21 @@  static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
 		for (node = rb_first(&process->fixed_lru[mem_type][i]); node;
 		     node = rb_next(node)) {
 			bo = rb_entry(node, struct ttm_buffer_object, node);
-			if (!ttm_bo_evict_swapout_allowable(bo, ctx, &locked))
+			if (!ttm_bo_evict_swapout_allowable(bo, ctx, &locked)) {
+				bo = NULL;
 				continue;
+			}
 
 			if (place && !bdev->driver->eviction_valuable(bo,
 								      place)) {
 				if (locked)
 					reservation_object_unlock(bo->resv);
+				bo = NULL;
 				continue;
 			}
 			break;
 		}
 
-		/* If the inner loop terminated early, we have our candidate */
-		if (&bo->lru != &process->fixed_lru[mem_type][i])
-			break;
-
-		bo = NULL;
 	}
 	if (bo)
 		break;