Commit 5b5c1777 authored by Josip Pavic's avatar Josip Pavic Committed by Alex Deucher

drm/amd/display: prevent loop from occuring in pipe list

[Why]
If no free pipes are available, acquire_first_split_pipe is called to
get a pipe to use. This call may alter the ordering of the pipes in the
list so that, for example, the tail pipe changes.

If acquire_first_split_pipe returns the tail pipe, we'll have free_pipe
== tail_pipe. What tail_pipe refers to is not the current tail_pipe, but
what was previously the tail pipe - i.e. prior to the call to
acquire_first_split_pipe

The logic that follows will link free_pipe to the tail pipe, referring to
the current tail pipe. However, since tail_pipe is cached from before the
call to acquire_first_split_pipe, the wrong tail pipe will be used, and
it will end up being linked to itself, creating a loop that, if traversed,
will result in a soft hang.

[How]
Do not cache the tail pipe. Instead, check the tail pipe after the call to
acquire_first_split_pipe is made.
Signed-off-by: default avatarJosip Pavic <Josip.Pavic@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 86f4a940
...@@ -1358,9 +1358,6 @@ bool dc_add_plane_to_context( ...@@ -1358,9 +1358,6 @@ bool dc_add_plane_to_context(
dc_plane_state_retain(plane_state); dc_plane_state_retain(plane_state);
while (head_pipe) { while (head_pipe) {
tail_pipe = resource_get_tail_pipe(&context->res_ctx, head_pipe);
ASSERT(tail_pipe);
free_pipe = acquire_free_pipe_for_head(context, pool, head_pipe); free_pipe = acquire_free_pipe_for_head(context, pool, head_pipe);
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
...@@ -1378,6 +1375,8 @@ bool dc_add_plane_to_context( ...@@ -1378,6 +1375,8 @@ bool dc_add_plane_to_context(
free_pipe->plane_state = plane_state; free_pipe->plane_state = plane_state;
if (head_pipe != free_pipe) { if (head_pipe != free_pipe) {
tail_pipe = resource_get_tail_pipe(&context->res_ctx, head_pipe);
ASSERT(tail_pipe);
free_pipe->stream_res.tg = tail_pipe->stream_res.tg; free_pipe->stream_res.tg = tail_pipe->stream_res.tg;
free_pipe->stream_res.abm = tail_pipe->stream_res.abm; free_pipe->stream_res.abm = tail_pipe->stream_res.abm;
free_pipe->stream_res.opp = tail_pipe->stream_res.opp; free_pipe->stream_res.opp = tail_pipe->stream_res.opp;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment