Every job submission on the Steam Deck ends up walking the list of IP
blocks looking for AMD_IP_BLOCK_TYPE_SMC. Half of the call chain is like
the below, while the second half is from amdgpu_gfx_profile_ring_end_use:

 amdgpu_gfx_profile_ring_begin_use
  amdgpu_dpm_is_overdrive_enabled
   is_support_sw_smu
    amdgpu_device_ip_is_valid

On a game menu screen at 90Hz refresh rate we end up with ~840 calls per
second which sticks out when the submission worker is profiled with perf:

  13.78%  [kernel]  [k] __lock_text_start
  10.86%  [kernel]  [k] __lookup_object
   8.76%  [kernel]  [k] __mod_timer
   4.94%  [kernel]  [k] queued_spin_lock_slowpath
   1.66%  [kernel]  [k] amdgpu_device_ip_is_valid
   1.54%  [kernel]  [k] preempt_count_add
   1.42%  [kernel]  [k] amdgpu_sync_peek_fence
   1.18%  [kernel]  [k] amdgpu_vmid_grab
   1.17%  [kernel]  [k] amdgpu_ib_schedule
   1.14%  [kernel]  [k] kthread_worker_fn

Lets short-circuit this walk by simply remembering a mask of valid IP
blocks. We could go a step further and remove a function call as well if
wanted.

I do not think the improvement here is easy to measure but it is at
least conceptually nicer to avoid repeating the same walk so much.

Signed-off-by: Tvrtko Ursulin <[email protected]>
Cc: Alex Deucher <[email protected]>
Cc: Christian König <[email protected]>
Cc: Timur Kristóf <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        | 1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c     | 8 +-------
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 7b09410d6d8f..5b3dd6c0baf8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1029,6 +1029,7 @@ struct amdgpu_device {
        struct amdgpu_cper              cper;
 
        struct amdgpu_ip_block          ip_blocks[AMDGPU_MAX_IP_NUM];
+       uint32_t                        ip_block_type_valid;
        uint32_t                        harvest_ip_mask;
        int                             num_ip_blocks;
        struct mutex    mn_lock;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 1e6b75ecafe4..e3c51ae2e61a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -2071,9 +2071,11 @@ static int amdgpu_device_ip_early_init(struct 
amdgpu_device *adev)
                                total = false;
                        } else {
                                adev->ip_blocks[i].status.valid = true;
+                               adev->ip_block_type_valid |= 
BIT(adev->ip_blocks[i].version->type);
                        }
                } else {
                        adev->ip_blocks[i].status.valid = true;
+                       adev->ip_block_type_valid |= 
BIT(adev->ip_blocks[i].version->type);
                }
                /* get the vbios after the asic_funcs are set up */
                if (adev->ip_blocks[i].version->type == 
AMD_IP_BLOCK_TYPE_COMMON) {
@@ -2923,6 +2925,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device 
*adev)
                }
                adev->ip_blocks[i].status.sw = false;
                adev->ip_blocks[i].status.valid = false;
+               adev->ip_block_type_valid &= 
~BIT(adev->ip_blocks[i].version->type);
        }
 
        for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c
index 6aa54156bbc9..d5cd3f19d2bf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c
@@ -401,11 +401,5 @@ bool amdgpu_device_ip_is_hw(struct amdgpu_device *adev,
 bool amdgpu_device_ip_is_valid(struct amdgpu_device *adev,
                               enum amd_ip_block_type block_type)
 {
-       struct amdgpu_ip_block *ip_block;
-
-       ip_block = amdgpu_device_ip_get_ip_block(adev, block_type);
-       if (ip_block)
-               return ip_block->status.valid;
-
-       return false;
+       return adev->ip_block_type_valid & BIT(block_type);
 }
-- 
2.54.0

Reply via email to