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