Allow the user to disable kernel queues.  This can be used
to free up vmid and HQD resources if kernel queues are not
needed.

Set amdgpu.user_queue=2 to disable kernel queues.

Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 117 ++++++++++++++++++++----
 1 file changed, 99 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
index 510266ba0c388..c7117ea6eec71 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
@@ -1107,22 +1107,24 @@ static int gfx_v9_4_3_sw_init(struct amdgpu_ip_block 
*ip_block)
        /* set up the compute queues - allocate horizontally across pipes */
        for (xcc_id = 0; xcc_id < num_xcc; xcc_id++) {
                ring_id = 0;
-               for (i = 0; i < adev->gfx.mec.num_mec; ++i) {
-                       for (j = 0; j < adev->gfx.mec.num_queue_per_pipe; j++) {
-                               for (k = 0; k < adev->gfx.mec.num_pipe_per_mec;
-                                    k++) {
-                                       if (!amdgpu_gfx_is_mec_queue_enabled(
-                                                       adev, xcc_id, i, k, j))
-                                               continue;
-
-                                       r = gfx_v9_4_3_compute_ring_init(adev,
-                                                                      ring_id,
-                                                                      xcc_id,
-                                                                      i, k, j);
-                                       if (r)
-                                               return r;
-
-                                       ring_id++;
+               if (!adev->gfx.disable_kq) {
+                       for (i = 0; i < adev->gfx.mec.num_mec; ++i) {
+                               for (j = 0; j < 
adev->gfx.mec.num_queue_per_pipe; j++) {
+                                       for (k = 0; k < 
adev->gfx.mec.num_pipe_per_mec;
+                                            k++) {
+                                               if 
(!amdgpu_gfx_is_mec_queue_enabled(
+                                                           adev, xcc_id, i, k, 
j))
+                                                       continue;
+
+                                               r = 
gfx_v9_4_3_compute_ring_init(adev,
+                                                                               
 ring_id,
+                                                                               
 xcc_id,
+                                                                               
 i, k, j);
+                                               if (r)
+                                                       return r;
+
+                                               ring_id++;
+                                       }
                                }
                        }
                }
@@ -2350,6 +2352,63 @@ static void gfx_v9_4_3_xcc_fini(struct amdgpu_device 
*adev, int xcc_id)
        gfx_v9_4_3_xcc_cp_compute_enable(adev, false, xcc_id);
 }
 
+static int gfx_v9_4_3_set_userq_eop_interrupts(struct amdgpu_device *adev,
+                                              bool enable)
+{
+       int num_xcc = NUM_XCC(adev->gfx.xcc_mask);
+       unsigned int irq_type;
+       int m, p, xcc_id, r;
+
+       if (adev->gfx.disable_kq) {
+               for (xcc_id = 0; xcc_id < num_xcc; xcc_id++) {
+                       for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
+                               for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; 
p++) {
+                                       irq_type = 
AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+                                               + (m * 
adev->gfx.mec.num_pipe_per_mec)
+                                               + p;
+
+                                       if (enable)
+                                               r = amdgpu_irq_get(adev, 
&adev->gfx.eop_irq,
+                                                                  irq_type);
+                                       else
+                                               r = amdgpu_irq_put(adev, 
&adev->gfx.eop_irq,
+                                                                  irq_type);
+                                       if (r) {
+                                               if (!enable)
+                                                       return r;
+                                               goto err_compute;
+                                       }
+                               }
+                       }
+               }
+       }
+
+err_compute:
+       for (p--; p >= 0; p--) {
+               irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+                       + (m * adev->gfx.mec.num_pipe_per_mec) + p;
+               amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+       }
+       for (m--; m >= 0; m--) {
+               for (p = adev->gfx.mec.num_pipe_per_mec - 1; p >= 0; p--) {
+                       irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+                               + (m * adev->gfx.mec.num_pipe_per_mec) + p;
+                       amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+               }
+       }
+       for (xcc_id--; xcc_id >= 0; xcc_id--) {
+               for (m = adev->gfx.mec.num_mec - 1; m <= 0; m--) {
+                       for (p = adev->gfx.mec.num_pipe_per_mec - 1; p >= 0; 
p--) {
+                               irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+                                       + (m * adev->gfx.mec.num_pipe_per_mec) 
+ p;
+                               amdgpu_irq_put(adev, &adev->gfx.eop_irq, 
irq_type);
+                       }
+               }
+       }
+
+       return r;
+}
+
 static int gfx_v9_4_3_hw_init(struct amdgpu_ip_block *ip_block)
 {
        int r;
@@ -2382,9 +2441,14 @@ static int gfx_v9_4_3_hw_init(struct amdgpu_ip_block 
*ip_block)
        r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
        if (r)
                goto err_bad_op;
+       r = gfx_v9_4_3_set_userq_eop_interrupts(adev, true);
+       if (r)
+               goto err_bad_eop;
 
        return 0;
 
+err_bad_eop:
+       amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
 err_bad_op:
        amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
 err_priv_inst:
@@ -2467,6 +2531,7 @@ static int gfx_v9_4_3_hw_fini(struct amdgpu_ip_block 
*ip_block)
        amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
        amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
        amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
+       gfx_v9_4_3_set_userq_eop_interrupts(adev, false);
 
        num_xcc = NUM_XCC(adev->gfx.xcc_mask);
        for (i = 0; i < num_xcc; i++) {
@@ -2612,8 +2677,24 @@ static int gfx_v9_4_3_early_init(struct amdgpu_ip_block 
*ip_block)
 {
        struct amdgpu_device *adev = ip_block->adev;
 
-       adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev),
-                                         AMDGPU_MAX_COMPUTE_RINGS);
+       switch (amdgpu_user_queue) {
+       case -1:
+       case 0:
+       default:
+               adev->gfx.disable_kq = false;
+               adev->gfx.disable_uq = true;
+               break;
+       case 2:
+               adev->gfx.disable_kq = true;
+               adev->gfx.disable_uq = true;
+               break;
+       }
+
+       if (adev->gfx.disable_kq)
+               adev->gfx.num_compute_rings = 0;
+       else
+               adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev),
+                                                 AMDGPU_MAX_COMPUTE_RINGS);
        gfx_v9_4_3_set_kiq_pm4_funcs(adev);
        gfx_v9_4_3_set_ring_funcs(adev);
        gfx_v9_4_3_set_irq_funcs(adev);
-- 
2.54.0

Reply via email to