mirror of https://gitee.com/openkylin/linux.git
drm/amdgpu: map compute rings by least recently used pipe
This patch provides a guarantee that the first n queues allocated by an application will be on different pipes. Where n is the number of pipes available from the hardware. This helps avoid ring aliasing which can result in work executing in time-sliced mode instead of truly parallel mode. Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Andres Rodriguez <andresx7@gmail.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
4a75aefe3f
commit
35161bbc13
|
@ -121,7 +121,7 @@ static enum amdgpu_ring_type amdgpu_hw_ip_to_ring_type(int hw_ip)
|
||||||
|
|
||||||
static int amdgpu_lru_map(struct amdgpu_device *adev,
|
static int amdgpu_lru_map(struct amdgpu_device *adev,
|
||||||
struct amdgpu_queue_mapper *mapper,
|
struct amdgpu_queue_mapper *mapper,
|
||||||
int user_ring,
|
int user_ring, bool lru_pipe_order,
|
||||||
struct amdgpu_ring **out_ring)
|
struct amdgpu_ring **out_ring)
|
||||||
{
|
{
|
||||||
int r, i, j;
|
int r, i, j;
|
||||||
|
@ -139,7 +139,7 @@ static int amdgpu_lru_map(struct amdgpu_device *adev,
|
||||||
}
|
}
|
||||||
|
|
||||||
r = amdgpu_ring_lru_get(adev, ring_type, ring_blacklist,
|
r = amdgpu_ring_lru_get(adev, ring_type, ring_blacklist,
|
||||||
j, out_ring);
|
j, lru_pipe_order, out_ring);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -284,8 +284,10 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev,
|
||||||
r = amdgpu_identity_map(adev, mapper, ring, out_ring);
|
r = amdgpu_identity_map(adev, mapper, ring, out_ring);
|
||||||
break;
|
break;
|
||||||
case AMDGPU_HW_IP_DMA:
|
case AMDGPU_HW_IP_DMA:
|
||||||
|
r = amdgpu_lru_map(adev, mapper, ring, false, out_ring);
|
||||||
|
break;
|
||||||
case AMDGPU_HW_IP_COMPUTE:
|
case AMDGPU_HW_IP_COMPUTE:
|
||||||
r = amdgpu_lru_map(adev, mapper, ring, out_ring);
|
r = amdgpu_lru_map(adev, mapper, ring, true, out_ring);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*out_ring = NULL;
|
*out_ring = NULL;
|
||||||
|
|
|
@ -315,14 +315,16 @@ static bool amdgpu_ring_is_blacklisted(struct amdgpu_ring *ring,
|
||||||
* @type: amdgpu_ring_type enum
|
* @type: amdgpu_ring_type enum
|
||||||
* @blacklist: blacklisted ring ids array
|
* @blacklist: blacklisted ring ids array
|
||||||
* @num_blacklist: number of entries in @blacklist
|
* @num_blacklist: number of entries in @blacklist
|
||||||
|
* @lru_pipe_order: find a ring from the least recently used pipe
|
||||||
* @ring: output ring
|
* @ring: output ring
|
||||||
*
|
*
|
||||||
* Retrieve the amdgpu_ring structure for the least recently used ring of
|
* Retrieve the amdgpu_ring structure for the least recently used ring of
|
||||||
* a specific IP block (all asics).
|
* a specific IP block (all asics).
|
||||||
* Returns 0 on success, error on failure.
|
* Returns 0 on success, error on failure.
|
||||||
*/
|
*/
|
||||||
int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist,
|
int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type,
|
||||||
int num_blacklist, struct amdgpu_ring **ring)
|
int *blacklist, int num_blacklist,
|
||||||
|
bool lru_pipe_order, struct amdgpu_ring **ring)
|
||||||
{
|
{
|
||||||
struct amdgpu_ring *entry;
|
struct amdgpu_ring *entry;
|
||||||
|
|
||||||
|
@ -337,10 +339,23 @@ int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist,
|
||||||
if (amdgpu_ring_is_blacklisted(entry, blacklist, num_blacklist))
|
if (amdgpu_ring_is_blacklisted(entry, blacklist, num_blacklist))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!*ring) {
|
||||||
*ring = entry;
|
*ring = entry;
|
||||||
amdgpu_ring_lru_touch_locked(adev, *ring);
|
|
||||||
|
/* We are done for ring LRU */
|
||||||
|
if (!lru_pipe_order)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Move all rings on the same pipe to the end of the list */
|
||||||
|
if (entry->pipe == (*ring)->pipe)
|
||||||
|
amdgpu_ring_lru_touch_locked(adev, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the ring we found to the end of the list */
|
||||||
|
if (*ring)
|
||||||
|
amdgpu_ring_lru_touch_locked(adev, *ring);
|
||||||
|
|
||||||
spin_unlock(&adev->ring_lru_list_lock);
|
spin_unlock(&adev->ring_lru_list_lock);
|
||||||
|
|
||||||
if (!*ring) {
|
if (!*ring) {
|
||||||
|
|
|
@ -201,8 +201,9 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
|
||||||
unsigned ring_size, struct amdgpu_irq_src *irq_src,
|
unsigned ring_size, struct amdgpu_irq_src *irq_src,
|
||||||
unsigned irq_type);
|
unsigned irq_type);
|
||||||
void amdgpu_ring_fini(struct amdgpu_ring *ring);
|
void amdgpu_ring_fini(struct amdgpu_ring *ring);
|
||||||
int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist,
|
int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type,
|
||||||
int num_blacklist, struct amdgpu_ring **ring);
|
int *blacklist, int num_blacklist,
|
||||||
|
bool lru_pipe_order, struct amdgpu_ring **ring);
|
||||||
void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring);
|
void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring);
|
||||||
static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring)
|
static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue