summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Jakobi <tjakobi@math.uni-bielefeld.de>2024-09-16 15:54:05 +0300
committerAlex Deucher <alexander.deucher@amd.com>2024-09-18 23:15:09 +0300
commite7d4e1438533abe448813bdc45691f9c230aa307 (patch)
treefc310cef649c0b9a4eb34184ecb848181f725cfd
parent375b035f689735fd7a87ff31ccac3a42717252bf (diff)
downloadlinux-e7d4e1438533abe448813bdc45691f9c230aa307.tar.xz
drm/amd/display: handle nulled pipe context in DCE110's set_drr()
As set_drr() is called from IRQ context, it can happen that the pipe context has been nulled by dc_state_destruct(). Apply the same protection here that is already present for dcn35_set_drr() and dcn10_set_drr(). I.e. fetch the tg pointer first (to avoid a race with dc_state_destruct()), and then check the local copy before using it. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3142 Fixes: 06ad7e164256 ("drm/amd/display: Destroy DC context while keeping DML and DML2") Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index aa7479b31898..4fbed0298adf 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -2096,13 +2096,20 @@ static void set_drr(struct pipe_ctx **pipe_ctx,
* as well.
*/
for (i = 0; i < num_pipes; i++) {
- pipe_ctx[i]->stream_res.tg->funcs->set_drr(
- pipe_ctx[i]->stream_res.tg, &params);
-
- if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
- pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
- pipe_ctx[i]->stream_res.tg,
- event_triggers, num_frames);
+ /* dc_state_destruct() might null the stream resources, so fetch tg
+ * here first to avoid a race condition. The lifetime of the pointee
+ * itself (the timing_generator object) is not a problem here.
+ */
+ struct timing_generator *tg = pipe_ctx[i]->stream_res.tg;
+
+ if ((tg != NULL) && tg->funcs) {
+ if (tg->funcs->set_drr)
+ tg->funcs->set_drr(tg, &params);
+ if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
+ if (tg->funcs->set_static_screen_control)
+ tg->funcs->set_static_screen_control(
+ tg, event_triggers, num_frames);
+ }
}
}