nc/core_types.h:598 and drivers/gpu/drm/amd/display/dc/inc/core_types.h:616. - Scope and side effects: - The change is confined to a single function in one file: drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c, used by DP CTS automation and debugfs-triggered training routines (see call sites at drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c:591 and drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c:321, :335, :455, :470, :3451, :3466). - No architectural changes. No new features. It’s a non-invasive correctness fix that avoids iterating over a state that may be swapped out mid-loop. - Risk of regression is low: logic mirrors existing behavior, only replacing “live read from `state->streams`” with a pre-cached snapshot. The link-matching predicate is unchanged. - Impact to users: - Prevents kernel crashes during DP LT automation and the debugfs paths that adjust preferred link settings/training. While not a typical end-user path, it is a valid in-kernel path and a kernel crash is a serious bug. - Alignment with stable rules: - Important bugfix that prevents a crash. - Small, well-contained, no new features, no architectural refactoring. - Touches a specific subsystem (AMDGPU DC DP accessory/CTS code) with minimal blast radius. - No explicit “Cc: stable” tag in the message, but the fix is straightforward and clearly justified. Notes - The patch still calls `dc_update_planes_and_stream(state->clk_mgr->ctx->dc, ...)`. Given the state swapping, using `link->dc` instead of `state->clk_mgr->ctx->dc` would be even more robust. However, the primary crash cause was iterating `state->streams` after the swap; caching streams resolves that. The rest of the code’s use of `state` is unchanged from pre- patch and has not been reported as problematic in this path. Conclusion - This is a clear, minimal crash fix in AMD DC’s DP LT automation path. It should be backported to stable trees where the affected code is present. .../display/dc/link/accessories/link_dp_cts.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c index b12d61701d4d9..23f41c99fa38c 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c @@ -76,6 +76,9 @@ static void dp_retrain_link_dp_test(struct dc_link *link, uint8_t count; int i; + struct dc_stream_state *streams_on_link[MAX_PIPES]; + int num_streams_on_link = 0; + needs_divider_update = (link->dc->link_srv->dp_get_encoding_format(link_setting) != link->dc->link_srv->dp_get_encoding_format((const struct dc_link_settings *) &link->cur_link_settings)); @@ -138,12 +141,19 @@ static void dp_retrain_link_dp_test(struct dc_link *link, pipes[i]->stream_res.tg->funcs->enable_crtc(pipes[i]->stream_res.tg); // Set DPMS on with stream update - for (i = 0; i < state->stream_count; i++) - if (state->streams[i] && state->streams[i]->link && state->streams[i]->link == link) { - stream_update.stream = state->streams[i]; + // Cache all streams on current link since dc_update_planes_and_stream might kill current_state + for (i = 0; i < MAX_PIPES; i++) { + if (state->streams[i] && state->streams[i]->link && state->streams[i]->link == link) + streams_on_link[num_streams_on_link++] = state->streams[i]; + } + + for (i = 0; i < num_streams_on_link; i++) { + if (streams_on_link[i] && streams_on_link[i]->link && streams_on_link[i]->link == link) { + stream_update.stream = streams_on_link[i]; stream_update.dpms_off = &dpms_off; - dc_update_planes_and_stream(state->clk_mgr->ctx->dc, NULL, 0, state->streams[i], &stream_update); + dc_update_planes_and_stream(state->clk_mgr->ctx->dc, NULL, 0, streams_on_link[i], &stream_update); } + } } static void dp_test_send_link_training(struct dc_link *link) -- 2.51.0[PATCH AUTOSEL 6.17] drm/amd/display: Cache streams targeting link when performing LT automationSasha Levin undefinedpatches@lists.linux.dev, stable@vger.kernel.org undefined undefined undefined undefined undefined undefined undefined undefined undefined undefined undefined:H