We were changing compute ring priority while rings were being used
before every job submission which is not recommended. This patch
recreates entity with higher/normal priority sched list when user
changes ctx's priority.

high/normal priority sched list are generated from set of high/normal
priority compute queues. When there are no high priority hw queues then
it fall backs to software priority.

Signed-off-by: Nirmoy Das <nirmoy....@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   |  4 --
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c  | 58 ++++++++++++++++++++++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h  |  2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c  |  6 ---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c |  4 ++
 5 files changed, 59 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index f397ff97b4e4..8304d0c87899 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1205,7 +1205,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
        struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
        struct drm_sched_entity *entity = p->entity;
        enum drm_sched_priority priority;
-       struct amdgpu_ring *ring;
        struct amdgpu_bo_list_entry *e;
        struct amdgpu_job *job;
        uint64_t seq;
@@ -1258,9 +1257,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
        priority = job->base.s_priority;
        drm_sched_entity_push_job(&job->base, entity);
 
-       ring = to_amdgpu_ring(entity->rq->sched);
-       amdgpu_ring_priority_get(ring, priority);
-
        amdgpu_vm_move_to_lru_tail(p->adev, &fpriv->vm);
 
        ttm_eu_fence_buffer_objects(&p->ticket, &p->validated, p->fence);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 94a6c42f29ea..ea4dc57d2237 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -85,8 +85,13 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, 
const u32 hw_ip, const
                        num_scheds = 1;
                        break;
                case AMDGPU_HW_IP_COMPUTE:
-                       scheds = adev->gfx.compute_sched;
-                       num_scheds = adev->gfx.num_compute_sched;
+                       if (priority <= DRM_SCHED_PRIORITY_NORMAL) {
+                               scheds = adev->gfx.compute_sched;
+                               num_scheds = adev->gfx.num_compute_sched;
+                       } else {
+                               scheds = adev->gfx.compute_sched_high;
+                               num_scheds = adev->gfx.num_compute_sched_high;
+                       }
                        break;
                case AMDGPU_HW_IP_DMA:
                        scheds = adev->sdma.sdma_sched;
@@ -502,6 +507,24 @@ struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx 
*ctx,
        return fence;
 }
 
+static void amdgpu_ctx_hw_priority_override(struct amdgpu_ctx *ctx,
+                                           const u32 hw_ip,
+                                           enum drm_sched_priority priority)
+{
+       int i;
+
+       for (i = 0; i < amdgpu_ctx_num_entities[hw_ip]; ++i) {
+               if (!ctx->entities[hw_ip][i])
+                       continue;
+
+               /* TODO what happens with prev scheduled jobs */
+               drm_sched_entity_destroy(&ctx->entities[hw_ip][i]->entity);
+               amdgpu_ctx_fini_entity(ctx->entities[hw_ip][i]);
+
+               amdgpu_ctx_init_entity(ctx, AMDGPU_HW_IP_COMPUTE, i);
+
+       }
+}
 void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx,
                                  enum drm_sched_priority priority)
 {
@@ -515,12 +538,18 @@ void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx,
        for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
                for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
                        struct drm_sched_entity *entity;
+                       struct amdgpu_ring *ring;
 
                        if (!ctx->entities[i][j])
                                continue;
 
                        entity = &ctx->entities[i][j]->entity;
-                       drm_sched_entity_set_priority(entity, ctx_prio);
+                       ring = to_amdgpu_ring(entity->rq->sched);
+
+                       if (ring->funcs->init_priority)
+                               amdgpu_ctx_hw_priority_override(ctx, i, 
priority);
+                       else
+                               drm_sched_entity_set_priority(entity, ctx_prio);
                }
        }
 }
@@ -630,6 +659,7 @@ void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr)
 
 void amdgpu_ctx_init_sched(struct amdgpu_device *adev)
 {
+       enum drm_sched_priority priority;
        int i, j;
 
        for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
@@ -638,8 +668,26 @@ void amdgpu_ctx_init_sched(struct amdgpu_device *adev)
        }
 
        for (i = 0; i < adev->gfx.num_compute_rings; i++) {
-               adev->gfx.compute_sched[i] = &adev->gfx.compute_ring[i].sched;
-               adev->gfx.num_compute_sched++;
+               priority = adev->gfx.compute_ring[i].priority;
+               if (priority <= DRM_SCHED_PRIORITY_NORMAL) {
+                       adev->gfx.compute_sched[i] =
+                               &adev->gfx.compute_ring[i].sched;
+                       adev->gfx.num_compute_sched++;
+               } else {
+                       adev->gfx.compute_sched_high[i] =
+                               &adev->gfx.compute_ring[i].sched;
+                       adev->gfx.num_compute_sched_high++;
+               }
+       }
+
+       /* if there are no high prio compute queue then mirror with normal
+        * priority so amdgpu_ctx_init_entity() works as expected */
+       if (!adev->gfx.num_compute_sched_high) {
+               for (i = 0; i < adev->gfx.num_compute_sched; i++) {
+                       adev->gfx.compute_sched_high[i] =
+                              adev->gfx.compute_sched[i];
+               }
+               adev->gfx.num_compute_sched_high = adev->gfx.num_compute_sched;
        }
 
        for (i = 0; i < adev->sdma.num_instances; i++) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
index ca17ffb01301..d58d748e3a56 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
@@ -279,7 +279,9 @@ struct amdgpu_gfx {
        unsigned                        num_gfx_rings;
        struct amdgpu_ring              compute_ring[AMDGPU_MAX_COMPUTE_RINGS];
        struct drm_gpu_scheduler        
*compute_sched[AMDGPU_MAX_COMPUTE_RINGS];
+       struct drm_gpu_scheduler        
*compute_sched_high[AMDGPU_MAX_COMPUTE_RINGS];
        uint32_t                        num_compute_sched;
+       uint32_t                        num_compute_sched_high;
        unsigned                        num_compute_rings;
        struct amdgpu_irq_src           eop_irq;
        struct amdgpu_irq_src           priv_reg_irq;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index d42be880a236..4981e443a884 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -117,12 +117,10 @@ void amdgpu_job_free_resources(struct amdgpu_job *job)
 
 static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
 {
-       struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched);
        struct amdgpu_job *job = to_amdgpu_job(s_job);
 
        drm_sched_job_cleanup(s_job);
 
-       amdgpu_ring_priority_put(ring, s_job->s_priority);
        dma_fence_put(job->fence);
        amdgpu_sync_free(&job->sync);
        amdgpu_sync_free(&job->sched_sync);
@@ -143,7 +141,6 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct 
drm_sched_entity *entity,
                      void *owner, struct dma_fence **f)
 {
        enum drm_sched_priority priority;
-       struct amdgpu_ring *ring;
        int r;
 
        if (!f)
@@ -158,9 +155,6 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct 
drm_sched_entity *entity,
        priority = job->base.s_priority;
        drm_sched_entity_push_job(&job->base, entity);
 
-       ring = to_amdgpu_ring(entity->rq->sched);
-       amdgpu_ring_priority_get(ring, priority);
-
        return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index 18e11b0fdc3e..4501ae7afb2e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -326,6 +326,10 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct 
amdgpu_ring *ring,
 
        ring->max_dw = max_dw;
        ring->priority = DRM_SCHED_PRIORITY_NORMAL;
+       if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE &&
+           ring->funcs->init_priority)
+               ring->funcs->init_priority(ring);
+
        mutex_init(&ring->priority_mutex);
 
        for (i = 0; i < DRM_SCHED_PRIORITY_MAX; ++i)
-- 
2.25.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to