]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/amdgpu: set compute queue priority at mqd_init
authorNirmoy Das <nirmoy.das@amd.com>
Thu, 27 Feb 2020 12:59:08 +0000 (13:59 +0100)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 9 Mar 2020 17:51:24 +0000 (13:51 -0400)
We were changing compute ring priority while rings were being used
before every job submission which is not recommended. This patch
sets compute queue priority at mqd initialization for gfx8, gfx9 and
gfx10.

Policy: make queue 0 of each pipe as high priority compute queue

High/normal priority compute sched lists are generated from set of high/normal
priority compute queues. At context creation, entity of compute queue
get a sched list from high or normal priority depending on ctx->priority

Signed-off-by: Nirmoy Das <nirmoy.das@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c

index f397ff97b4e446d6b48c59e18fc58d65ba217a93..8304d0c878990757d3aac10669175dda3d37d1e7 100644 (file)
@@ -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);
index 94a6c42f29ea59a42f62bc1ef1077e21566df3a1..1d05eb64b8852a8c23f1e2439ed1d8cba564f02b 100644 (file)
@@ -61,12 +61,24 @@ static int amdgpu_ctx_priority_permit(struct drm_file *filp,
        return -EACCES;
 }
 
+static enum gfx_pipe_priority amdgpu_ctx_sched_prio_to_compute_prio(enum drm_sched_priority prio)
+{
+       switch (prio) {
+       case DRM_SCHED_PRIORITY_HIGH_HW:
+       case DRM_SCHED_PRIORITY_KERNEL:
+               return AMDGPU_GFX_PIPE_PRIO_HIGH;
+       default:
+               return AMDGPU_GFX_PIPE_PRIO_NORMAL;
+       }
+}
+
 static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, const u32 hw_ip, const u32 ring)
 {
        struct amdgpu_device *adev = ctx->adev;
        struct amdgpu_ctx_entity *entity;
        struct drm_gpu_scheduler **scheds = NULL, *sched = NULL;
        unsigned num_scheds = 0;
+       enum gfx_pipe_priority hw_prio;
        enum drm_sched_priority priority;
        int r;
 
@@ -85,8 +97,9 @@ 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;
+                       hw_prio = amdgpu_ctx_sched_prio_to_compute_prio(priority);
+                       scheds = adev->gfx.compute_prio_sched[hw_prio];
+                       num_scheds = adev->gfx.num_compute_sched[hw_prio];
                        break;
                case AMDGPU_HW_IP_DMA:
                        scheds = adev->sdma.sdma_sched;
@@ -628,20 +641,46 @@ void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr)
        mutex_destroy(&mgr->lock);
 }
 
+
+static void amdgpu_ctx_init_compute_sched(struct amdgpu_device *adev)
+{
+       int num_compute_sched_normal = 0;
+       int num_compute_sched_high = AMDGPU_MAX_COMPUTE_RINGS - 1;
+       int i;
+
+       /* use one drm sched array, gfx.compute_sched to store both high and
+        * normal priority drm compute schedulers */
+       for (i = 0; i < adev->gfx.num_compute_rings; i++) {
+               if (!adev->gfx.compute_ring[i].has_high_prio)
+                       adev->gfx.compute_sched[num_compute_sched_normal++] =
+                               &adev->gfx.compute_ring[i].sched;
+               else
+                       adev->gfx.compute_sched[num_compute_sched_high--] =
+                               &adev->gfx.compute_ring[i].sched;
+       }
+
+       /* compute ring only has two priority for now */
+       i = AMDGPU_GFX_PIPE_PRIO_NORMAL;
+       adev->gfx.compute_prio_sched[i] = &adev->gfx.compute_sched[0];
+       adev->gfx.num_compute_sched[i] = num_compute_sched_normal;
+
+       i = AMDGPU_GFX_PIPE_PRIO_HIGH;
+       adev->gfx.compute_prio_sched[i] =
+               &adev->gfx.compute_sched[num_compute_sched_high - 1];
+       adev->gfx.num_compute_sched[i] =
+               adev->gfx.num_compute_rings - num_compute_sched_normal;
+}
+
 void amdgpu_ctx_init_sched(struct amdgpu_device *adev)
 {
        int i, j;
 
+       amdgpu_ctx_init_compute_sched(adev);
        for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
                adev->gfx.gfx_sched[i] = &adev->gfx.gfx_ring[i].sched;
                adev->gfx.num_gfx_sched++;
        }
 
-       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++;
-       }
-
        for (i = 0; i < adev->sdma.num_instances; i++) {
                adev->sdma.sdma_sched[i] = &adev->sdma.instance[i].ring.sched;
                adev->sdma.num_sdma_sched++;
index 7403588684b3462c41a37e76d98e9c6fc3bd532e..952725e7243c4b340fec2009911920f1a07a3574 100644 (file)
@@ -192,6 +192,14 @@ static bool amdgpu_gfx_is_multipipe_capable(struct amdgpu_device *adev)
        return adev->gfx.mec.num_mec > 1;
 }
 
+bool amdgpu_gfx_is_high_priority_compute_queue(struct amdgpu_device *adev,
+                                              int queue)
+{
+       /* Policy: make queue 0 of each pipe as high priority compute queue */
+       return (queue == 0);
+
+}
+
 void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev)
 {
        int i, queue, pipe, mec;
index bb05cb7b3f085ddb0530da9baaea243ce14e0ca2..5825692d07e42a33a31004bebd6b7ebcb4936b09 100644 (file)
 #define AMDGPU_MAX_GFX_QUEUES KGD_MAX_QUEUES
 #define AMDGPU_MAX_COMPUTE_QUEUES KGD_MAX_QUEUES
 
+enum gfx_pipe_priority {
+       AMDGPU_GFX_PIPE_PRIO_NORMAL = 1,
+       AMDGPU_GFX_PIPE_PRIO_HIGH,
+       AMDGPU_GFX_PIPE_PRIO_MAX
+};
+
+#define AMDGPU_GFX_QUEUE_PRIORITY_MINIMUM  0
+#define AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM  15
+
 struct amdgpu_mec {
        struct amdgpu_bo        *hpd_eop_obj;
        u64                     hpd_eop_gpu_addr;
@@ -281,8 +290,9 @@ struct amdgpu_gfx {
        uint32_t                        num_gfx_sched;
        unsigned                        num_gfx_rings;
        struct amdgpu_ring              compute_ring[AMDGPU_MAX_COMPUTE_RINGS];
+       struct drm_gpu_scheduler        **compute_prio_sched[AMDGPU_GFX_PIPE_PRIO_MAX];
        struct drm_gpu_scheduler        *compute_sched[AMDGPU_MAX_COMPUTE_RINGS];
-       uint32_t                        num_compute_sched;
+       uint32_t                        num_compute_sched[AMDGPU_GFX_PIPE_PRIO_MAX];
        unsigned                        num_compute_rings;
        struct amdgpu_irq_src           eop_irq;
        struct amdgpu_irq_src           priv_reg_irq;
@@ -364,6 +374,8 @@ void amdgpu_gfx_bit_to_mec_queue(struct amdgpu_device *adev, int bit,
                                 int *mec, int *pipe, int *queue);
 bool amdgpu_gfx_is_mec_queue_enabled(struct amdgpu_device *adev, int mec,
                                     int pipe, int queue);
+bool amdgpu_gfx_is_high_priority_compute_queue(struct amdgpu_device *adev,
+                                              int queue);
 int amdgpu_gfx_me_queue_to_bit(struct amdgpu_device *adev, int me,
                               int pipe, int queue);
 void amdgpu_gfx_bit_to_me_queue(struct amdgpu_device *adev, int bit,
index d42be880a236bf8b1d0278a5c9586a0fc25ccdd9..4981e443a88473050e27559e4f43acc1c5a13d58 100644 (file)
@@ -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;
 }
 
index 24caff085d0046e5e9456b85c8333ab0b002d7e6..dcea1ef92883c3dd4ab6efe5c452fe9df581bc6e 100644 (file)
@@ -222,6 +222,7 @@ struct amdgpu_ring {
        struct mutex            priority_mutex;
        /* protected by priority_mutex */
        int                     priority;
+       bool                    has_high_prio;
 
 #if defined(CONFIG_DEBUG_FS)
        struct dentry *ent;
index 925b92b14f96de387657ad403eb1468a952076a3..614e910643ef16f9f3003572ee8de1d99f3a0caa 100644 (file)
@@ -3213,6 +3213,22 @@ done:
        return r;
 }
 
+static void gfx_v10_0_compute_mqd_set_priority(struct amdgpu_ring *ring, struct v10_compute_mqd *mqd)
+{
+       struct amdgpu_device *adev = ring->adev;
+
+       if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
+               if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue)) {
+                       mqd->cp_hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH;
+                       ring->has_high_prio = true;
+                       mqd->cp_hqd_queue_priority =
+                               AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM;
+               } else {
+                       ring->has_high_prio = false;
+               }
+       }
+}
+
 static int gfx_v10_0_compute_mqd_init(struct amdgpu_ring *ring)
 {
        struct amdgpu_device *adev = ring->adev;
@@ -3338,6 +3354,9 @@ static int gfx_v10_0_compute_mqd_init(struct amdgpu_ring *ring)
        tmp = REG_SET_FIELD(tmp, CP_HQD_IB_CONTROL, MIN_IB_AVAIL_SIZE, 3);
        mqd->cp_hqd_ib_control = tmp;
 
+       /* set static priority for a compute queue/ring */
+       gfx_v10_0_compute_mqd_set_priority(ring, mqd);
+
        /* map_queues packet doesn't need activate the queue,
         * so only kiq need set this field.
         */
index b14f46a3b11d83361f8bc7a6691d4e877cf29887..75bd7615e6eb1f1132a3fbd787df640aba03fbf5 100644 (file)
@@ -4430,6 +4430,22 @@ static int gfx_v8_0_deactivate_hqd(struct amdgpu_device *adev, u32 req)
        return r;
 }
 
+static void gfx_v8_0_mqd_set_priority(struct amdgpu_ring *ring, struct vi_mqd *mqd)
+{
+       struct amdgpu_device *adev = ring->adev;
+
+       if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
+               if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue)) {
+                       mqd->cp_hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH;
+                       ring->has_high_prio = true;
+                       mqd->cp_hqd_queue_priority =
+                               AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM;
+               } else {
+                       ring->has_high_prio = false;
+               }
+       }
+}
+
 static int gfx_v8_0_mqd_init(struct amdgpu_ring *ring)
 {
        struct amdgpu_device *adev = ring->adev;
@@ -4553,9 +4569,6 @@ static int gfx_v8_0_mqd_init(struct amdgpu_ring *ring)
        /* defaults */
        mqd->cp_hqd_eop_rptr = RREG32(mmCP_HQD_EOP_RPTR);
        mqd->cp_hqd_eop_wptr = RREG32(mmCP_HQD_EOP_WPTR);
-       mqd->cp_hqd_pipe_priority = RREG32(mmCP_HQD_PIPE_PRIORITY);
-       mqd->cp_hqd_queue_priority = RREG32(mmCP_HQD_QUEUE_PRIORITY);
-       mqd->cp_hqd_quantum = RREG32(mmCP_HQD_QUANTUM);
        mqd->cp_hqd_ctx_save_base_addr_lo = RREG32(mmCP_HQD_CTX_SAVE_BASE_ADDR_LO);
        mqd->cp_hqd_ctx_save_base_addr_hi = RREG32(mmCP_HQD_CTX_SAVE_BASE_ADDR_HI);
        mqd->cp_hqd_cntl_stack_offset = RREG32(mmCP_HQD_CNTL_STACK_OFFSET);
@@ -4567,6 +4580,10 @@ static int gfx_v8_0_mqd_init(struct amdgpu_ring *ring)
        mqd->cp_hqd_eop_wptr_mem = RREG32(mmCP_HQD_EOP_WPTR_MEM);
        mqd->cp_hqd_eop_dones = RREG32(mmCP_HQD_EOP_DONES);
 
+       /* set static priority for a queue/ring */
+       gfx_v8_0_mqd_set_priority(ring, mqd);
+       mqd->cp_hqd_quantum = RREG32(mmCP_HQD_QUANTUM);
+
        /* map_queues packet doesn't need activate the queue,
         * so only kiq need set this field.
         */
index 9726ecb1ec61a8424cfc43a9af79f4b86d2ef422..445b44986080b81b33ee1fa888d54b70f658c7b0 100644 (file)
@@ -3316,6 +3316,22 @@ static void gfx_v9_0_kiq_setting(struct amdgpu_ring *ring)
        WREG32_SOC15_RLC(GC, 0, mmRLC_CP_SCHEDULERS, tmp);
 }
 
+static void gfx_v9_0_mqd_set_priority(struct amdgpu_ring *ring, struct v9_mqd *mqd)
+{
+       struct amdgpu_device *adev = ring->adev;
+
+       if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
+               if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue)) {
+                       mqd->cp_hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH;
+                       ring->has_high_prio = true;
+                       mqd->cp_hqd_queue_priority =
+                               AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM;
+               } else {
+                       ring->has_high_prio = false;
+               }
+       }
+}
+
 static int gfx_v9_0_mqd_init(struct amdgpu_ring *ring)
 {
        struct amdgpu_device *adev = ring->adev;
@@ -3452,6 +3468,10 @@ static int gfx_v9_0_mqd_init(struct amdgpu_ring *ring)
        tmp = REG_SET_FIELD(tmp, CP_HQD_IB_CONTROL, MIN_IB_AVAIL_SIZE, 3);
        mqd->cp_hqd_ib_control = tmp;
 
+       /* set static priority for a queue/ring */
+       gfx_v9_0_mqd_set_priority(ring, mqd);
+       mqd->cp_hqd_quantum = RREG32(mmCP_HQD_QUANTUM);
+
        /* map_queues packet doesn't need activate the queue,
         * so only kiq need set this field.
         */