[PATCH 25/36] drm/amd/display: Fix warning caused by an attempt to configure a non-otg master

Hamza Mahfooz hamza.mahfooz at amd.com
Tue Jun 11 16:51:28 UTC 2024


From: Rodrigo Siqueira <rodrigo.siqueira at amd.com>

When booting the system with DCN401, the driver adds the following dmesg
warning:

WARNING: CPU: 8 PID: 175 at
drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_resource.c:1923
resource_get_opp_heads_for_otg_master+0x13/0x70 [amdgpu]

Modules linked in: amdgpu(+) hid_generic amdxcp i2c_algo_bit
drm_ttm_helper ttm drm_exec gpu_sched drm_suballoc_helper drm_buddy
drm_display_helper drm_kms_helper usbhid hid drm i2c_piix4 ahci igc
libahci video wmi

CPU: 8 PID: 175 Comm: systemd-udevd Not tainted 6.8.0-EXTRA-PROMO-MAY-29+ #66
Hardware name: ASUS System Product Name/TUF GAMING X570-PRO (WI-FI),
BIOS 4021 08/10/2021

RIP: 0010:resource_get_opp_heads_for_otg_master+0x13/0x70 [amdgpu]
Code: 8b 66 0f 1f 44 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 0f 1f 44 00 00 55 48 83 bf f8 07 00 00 00 48 89 e5 74 0c <0f> 0b 31
f6 89 f0 5d e9 0c 65 01 e5 48 83 bf e0 07 00 00 00 75 ea

RSP: 0018:ffffa5f000816ed8 EFLAGS: 00010246
[...]
PKRU: 55555554
Call Trace:
 <TASK>
 ? show_regs+0x65/0x70
 ? __warn+0x85/0x160
 ? resource_get_opp_heads_for_otg_master+0x13/0x70 [amdgpu]
 ? report_bug+0x192/0x1c0
 ? handle_bug+0x44/0x90
 ? exc_invalid_op+0x18/0x70
[...]

This warning is triggered by a check in the function
resource_get_opp_heads_for_otg_master that validates if the request
operation is in a master OTG pipe; if not, the warning above is
displayed. In other words, another part of the code might be calling
this function in a non-OTG master pipe context, resulting in the log
message.

The reason the ASSERT was triggered is that the current state wasn't
updated after applying the context to the hardware. This means that the
update_dsc_for_odm_change might be called from a non-OTG-MASTER. To
prevent this, it's crucial to check if the current reference is pointing
to an OTG master before operate in the old OTG master reference. If it's
not, the function must set the old OTG reference to NULL and avoid
calling resource_get_opp_heads_for_otg_master before the context is
updated.

Reviewed-by: Wenjing Liu <wenjing.liu at amd.com>
Acked-by: Hamza Mahfooz <hamza.mahfooz at amd.com>
Co-developed-by: Wenjing Liu <wenjing.liu at amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu at amd.com>
Signed-off-by: Rodrigo Siqueira <rodrigo.siqueira at amd.com>
---
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 24 ++++++++++++++-----
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 0fafbec442b1..cb8e417fb032 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -1561,16 +1561,28 @@ static void update_dsc_for_odm_change(struct dc *dc, struct dc_state *context,
 	struct pipe_ctx *new_pipe;
 	struct pipe_ctx *old_opp_heads[MAX_PIPES];
 	struct dccg *dccg = dc->res_pool->dccg;
-	struct pipe_ctx *old_otg_master =
-			&dc->current_state->res_ctx.pipe_ctx[otg_master->pipe_idx];
-	int old_opp_head_count = resource_get_opp_heads_for_otg_master(
-			old_otg_master, &dc->current_state->res_ctx,
-			old_opp_heads);
+	struct pipe_ctx *old_otg_master;
+	int old_opp_head_count = 0;
+
+	old_otg_master = &dc->current_state->res_ctx.pipe_ctx[otg_master->pipe_idx];
+
+	if (resource_is_pipe_type(old_otg_master, OTG_MASTER)) {
+		old_opp_head_count = resource_get_opp_heads_for_otg_master(old_otg_master,
+									   &dc->current_state->res_ctx,
+									   old_opp_heads);
+	} else {
+		// DC cannot assume that the current state and the new state
+		// share the same OTG pipe since this is not true when called
+		// in the context of a commit stream not checked. Hence, set
+		// old_otg_master to NULL to skip the DSC configuration.
+		old_otg_master = NULL;
+	}
+
 
 	if (otg_master->stream_res.dsc)
 		dcn32_update_dsc_on_stream(otg_master,
 				otg_master->stream->timing.flags.DSC);
-	if (old_otg_master->stream_res.dsc) {
+	if (old_otg_master && old_otg_master->stream_res.dsc) {
 		for (i = 0; i < old_opp_head_count; i++) {
 			old_pipe = old_opp_heads[i];
 			new_pipe = &context->res_ctx.pipe_ctx[old_pipe->pipe_idx];
-- 
2.45.1



More information about the amd-gfx mailing list