aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAndres Rodriguez <andresx7@gmail.com>2017-03-17 14:30:15 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-05-31 16:49:03 -0400
commit6065343a116fce16f7523ab10841efd942ce612d (patch)
treec21ee48ee40775c1705cdd931b28ddb643be8f91 /drivers/gpu
parent795f2813e628bcf57a69f2dfe413360d14a1d7f4 (diff)
drm/amdgpu: guarantee bijective mapping of ring ids for LRU v3
Depending on usage patterns, the current LRU policy may create a non-injective mapping between userspace ring ids and kernel rings. This behaviour is undesired as apps that attempt to fill all HW blocks would be unable to reach some of them. This change forces the LRU policy to create bijective mappings only. v2: compress ring_blacklist v3: simplify amdgpu_ring_is_blacklisted() logic Signed-off-by: Andres Rodriguez <andresx7@gmail.com> Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c16
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c33
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h4
3 files changed, 42 insertions, 11 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
index 4073f072f6c4..9a14c27d99d7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
@@ -124,10 +124,22 @@ static int amdgpu_lru_map(struct amdgpu_device *adev,
124 int user_ring, 124 int user_ring,
125 struct amdgpu_ring **out_ring) 125 struct amdgpu_ring **out_ring)
126{ 126{
127 int r; 127 int r, i, j;
128 int ring_type = amdgpu_hw_ip_to_ring_type(mapper->hw_ip); 128 int ring_type = amdgpu_hw_ip_to_ring_type(mapper->hw_ip);
129 int ring_blacklist[AMDGPU_MAX_RINGS];
130 struct amdgpu_ring *ring;
129 131
130 r = amdgpu_ring_lru_get(adev, ring_type, out_ring); 132 /* 0 is a valid ring index, so initialize to -1 */
133 memset(ring_blacklist, 0xff, sizeof(ring_blacklist));
134
135 for (i = 0, j = 0; i < AMDGPU_MAX_RINGS; i++) {
136 ring = mapper->queue_map[i];
137 if (ring)
138 ring_blacklist[j++] = ring->idx;
139 }
140
141 r = amdgpu_ring_lru_get(adev, ring_type, ring_blacklist,
142 j, out_ring);
131 if (r) 143 if (r)
132 return r; 144 return r;
133 145
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index f1076e3edf53..cef135ef7334 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -338,19 +338,34 @@ static void amdgpu_ring_lru_touch_locked(struct amdgpu_device *adev,
338 list_move_tail(&ring->lru_list, &adev->ring_lru_list); 338 list_move_tail(&ring->lru_list, &adev->ring_lru_list);
339} 339}
340 340
341static bool amdgpu_ring_is_blacklisted(struct amdgpu_ring *ring,
342 int *blacklist, int num_blacklist)
343{
344 int i;
345
346 for (i = 0; i < num_blacklist; i++) {
347 if (ring->idx == blacklist[i])
348 return true;
349 }
350
351 return false;
352}
353
341/** 354/**
342 * amdgpu_ring_lru_get - get the least recently used ring for a HW IP block 355 * amdgpu_ring_lru_get - get the least recently used ring for a HW IP block
343 * 356 *
344 * @adev: amdgpu_device pointer 357 * @adev: amdgpu_device pointer
345 * @type: amdgpu_ring_type enum 358 * @type: amdgpu_ring_type enum
359 * @blacklist: blacklisted ring ids array
360 * @num_blacklist: number of entries in @blacklist
346 * @ring: output ring 361 * @ring: output ring
347 * 362 *
348 * Retrieve the amdgpu_ring structure for the least recently used ring of 363 * Retrieve the amdgpu_ring structure for the least recently used ring of
349 * a specific IP block (all asics). 364 * a specific IP block (all asics).
350 * Returns 0 on success, error on failure. 365 * Returns 0 on success, error on failure.
351 */ 366 */
352int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, 367int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist,
353 struct amdgpu_ring **ring) 368 int num_blacklist, struct amdgpu_ring **ring)
354{ 369{
355 struct amdgpu_ring *entry; 370 struct amdgpu_ring *entry;
356 371
@@ -359,11 +374,15 @@ int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type,
359 *ring = NULL; 374 *ring = NULL;
360 spin_lock(&adev->ring_lru_list_lock); 375 spin_lock(&adev->ring_lru_list_lock);
361 list_for_each_entry(entry, &adev->ring_lru_list, lru_list) { 376 list_for_each_entry(entry, &adev->ring_lru_list, lru_list) {
362 if (entry->funcs->type == type) { 377 if (entry->funcs->type != type)
363 *ring = entry; 378 continue;
364 amdgpu_ring_lru_touch_locked(adev, *ring); 379
365 break; 380 if (amdgpu_ring_is_blacklisted(entry, blacklist, num_blacklist))
366 } 381 continue;
382
383 *ring = entry;
384 amdgpu_ring_lru_touch_locked(adev, *ring);
385 break;
367 } 386 }
368 spin_unlock(&adev->ring_lru_list_lock); 387 spin_unlock(&adev->ring_lru_list_lock);
369 388
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index 577528a9af0b..a1dd9077c064 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -201,8 +201,8 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
201 unsigned ring_size, struct amdgpu_irq_src *irq_src, 201 unsigned ring_size, struct amdgpu_irq_src *irq_src,
202 unsigned irq_type); 202 unsigned irq_type);
203void amdgpu_ring_fini(struct amdgpu_ring *ring); 203void amdgpu_ring_fini(struct amdgpu_ring *ring);
204int amdgpu_ring_lru_get(struct amdgpu_device *adev, int hw_ip, 204int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist,
205 struct amdgpu_ring **ring); 205 int num_blacklist, struct amdgpu_ring **ring);
206void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring); 206void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring);
207static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) 207static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring)
208{ 208{