[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