[PATCH] drm/amdgpu: map compute rings by least recently used pipe
Alex Deucher
alexdeucher at gmail.com
Thu Sep 28 19:16:22 UTC 2017
On Tue, Sep 26, 2017 at 5:43 PM, Andres Rodriguez <andresx7 at gmail.com> wrote:
> 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 <andresx7 at gmail.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
And applied.
Alex
> ---
> 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(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
> index befc09b..190e28c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
> @@ -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;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
> index 5ce6528..019932a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
> @@ -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) {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
> index 322d2529..491bd55 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
> @@ -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
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
More information about the amd-gfx
mailing list