drm/amdgpu: map compute rings by least recently used pipe
Subsystems (2)
PATCH 1/1 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.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c | 8 +++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 25 ++++++++++++++++++++----- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 5 +++-- 3 files changed, 28 insertions(+), 10 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c +5 -3
@@ -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,struct amdgpu_queue_mapper *mapper, -int user_ring, +int user_ring,bool lru_pipe_order,struct amdgpu_ring **out_ring) {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, - j, out_ring); + j, lru_pipe_order, out_ring);if (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);break ;case AMDGPU_HW_IP_DMA : + r =amdgpu_lru_map (adev, mapper, ring, false, out_ring); +break ;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 ;default : *out_ring =NULL ;
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +20 -5
@@ -315,14 +315,16 @@ static bool amdgpu_ring_is_blacklisted(struct amdgpu_ring *ring,* @type: amdgpu_ring_type enum * @blacklist: blacklisted ring ids array * @num_blacklist: number of entries in @blacklist +* @lru_pipe_order: find a ring from the least recently used pipe * @ring: output ring * * Retrieve the amdgpu_ring structure for the least recently used ring of * a specific IP block (all asics). * Returns 0 on success, error on failure. */ -int amdgpu_ring_lru_get (struct amdgpu_device *adev,int type,int *blacklist, -int num_blacklist,struct amdgpu_ring **ring) +int amdgpu_ring_lru_get (struct amdgpu_device *adev,int type, +int *blacklist,int num_blacklist, +bool lru_pipe_order,struct amdgpu_ring **ring) {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))continue ; - *ring = entry; -amdgpu_ring_lru_touch_locked (adev, *ring); -break ; +if (!*ring) { + *ring = entry; + +/* We are done for ring LRU */ +if (!lru_pipe_order) +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);if (!*ring) {
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +3 -2
@@ -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 irq_type);void amdgpu_ring_fini (struct amdgpu_ring *ring); -int amdgpu_ring_lru_get (struct amdgpu_device *adev,int type,int *blacklist, -int num_blacklist,struct amdgpu_ring **ring); +int amdgpu_ring_lru_get (struct amdgpu_device *adev,int type, +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);static inline void amdgpu_ring_clear_ring (struct amdgpu_ring *ring) {
Signature · 6 lines
2.9.3 _______________________________________________ amd-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/amd-gfx
A message that is not in the archive (sent off-list or not yet received): 20170926214314.3223-1-andresx7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Alex Deucher
Reviewed-byQuoted 8 lines · Andres Rodriguez
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.
Signed-off-by Andres Rodriguez <[email protected]>
And applied.
Alex
Quoted 109 lines
--- drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c | 8 +++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 25 ++++++++++++++++++++----- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 5 +++-- 3 files changed, 28 insertions(+), 10 deletions(-)drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c +5
-3@@ -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,struct amdgpu_queue_mapper *mapper, -int user_ring, +int user_ring,bool lru_pipe_order,struct amdgpu_ring **out_ring) {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, - j, out_ring); + j, lru_pipe_order, out_ring);if (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);break ;case AMDGPU_HW_IP_DMA : + r =amdgpu_lru_map (adev, mapper, ring, false, out_ring); +break ;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 ;default : *out_ring =NULL ;drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +20
-5@@ -315,14 +315,16 @@ static bool amdgpu_ring_is_blacklisted(struct amdgpu_ring *ring,* @type: amdgpu_ring_type enum * @blacklist: blacklisted ring ids array * @num_blacklist: number of entries in @blacklist +* @lru_pipe_order: find a ring from the least recently used pipe * @ring: output ring * * Retrieve the amdgpu_ring structure for the least recently used ring of * a specific IP block (all asics). * Returns 0 on success, error on failure. */ -int amdgpu_ring_lru_get (struct amdgpu_device *adev,int type,int *blacklist, -int num_blacklist,struct amdgpu_ring **ring) +int amdgpu_ring_lru_get (struct amdgpu_device *adev,int type, +int *blacklist,int num_blacklist, +bool lru_pipe_order,struct amdgpu_ring **ring) {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))continue ; - *ring = entry; -amdgpu_ring_lru_touch_locked (adev, *ring); -break ; +if (!*ring) { + *ring = entry; + +/* We are done for ring LRU */ +if (!lru_pipe_order) +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);if (!*ring) {drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +3
-3@@ -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 irq_type);void amdgpu_ring_fini (struct amdgpu_ring *ring); -int amdgpu_ring_lru_get (struct amdgpu_device *adev,int type,int *blacklist, -int num_blacklist,struct amdgpu_ring **ring); +int amdgpu_ring_lru_get (struct amdgpu_device *adev,int type, +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);static inline void amdgpu_ring_clear_ring (struct amdgpu_ring *ring) { --2.9.3
Quoted 4 lines
_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx