Skip to content

Commit 77fcf58

Browse files
ideakjlahtine-intel
authored andcommitted
drm/i915/dp_tunnel: Fix error handling when clearing stream BW in atomic state
Clearing the DP tunnel stream BW in the atomic state involves getting the tunnel group state, which can fail. Handle the error accordingly. This fixes at least one issue where drm_dp_tunnel_atomic_set_stream_bw() failed to get the tunnel group state returning -EDEADLK, which wasn't handled. This lead to the ctx->contended warn later in modeset_lock() while taking a WW mutex for another object in the same atomic state, and thus within the same already contended WW context. Moving intel_crtc_state_alloc() later would avoid freeing saved_state on the error path; this stable patch leaves that simplification for a follow-up. Cc: Uma Shankar <[email protected]> Cc: Ville Syrjälä <[email protected]> Cc: <[email protected]> # v6.9+ Fixes: a4efae8 ("drm/i915/dp: Compute DP tunnel BW during encoder state computation") Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/7617 Reviewed-by: Michał Grzelak <[email protected]> Reviewed-by: Uma Shankar <[email protected]> Signed-off-by: Imre Deak <[email protected]> Link: https://patch.msgid.link/[email protected] (cherry picked from commit fb69d00) Signed-off-by: Joonas Lahtinen <[email protected]>
1 parent bfa71b7 commit 77fcf58

3 files changed

Lines changed: 28 additions & 11 deletions

File tree

drivers/gpu/drm/i915/display/intel_display.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4602,6 +4602,7 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
46024602
struct intel_crtc_state *crtc_state =
46034603
intel_atomic_get_new_crtc_state(state, crtc);
46044604
struct intel_crtc_state *saved_state;
4605+
int err;
46054606

46064607
saved_state = intel_crtc_state_alloc(crtc);
46074608
if (!saved_state)
@@ -4610,7 +4611,12 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
46104611
/* free the old crtc_state->hw members */
46114612
intel_crtc_free_hw_state(crtc_state);
46124613

4613-
intel_dp_tunnel_atomic_clear_stream_bw(state, crtc_state);
4614+
err = intel_dp_tunnel_atomic_clear_stream_bw(state, crtc_state);
4615+
if (err) {
4616+
kfree(saved_state);
4617+
4618+
return err;
4619+
}
46144620

46154621
/* FIXME: before the switch to atomic started, a new pipe_config was
46164622
* kzalloc'd. Code that depends on any field being zero should be

drivers/gpu/drm/i915/display/intel_dp_tunnel.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -621,19 +621,27 @@ int intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state *state,
621621
*
622622
* Clear any DP tunnel stream BW requirement set by
623623
* intel_dp_tunnel_atomic_compute_stream_bw().
624+
*
625+
* Returns 0 in case of success, a negative error code otherwise.
624626
*/
625-
void intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
626-
struct intel_crtc_state *crtc_state)
627+
int intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
628+
struct intel_crtc_state *crtc_state)
627629
{
628630
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
631+
int err;
629632

630633
if (!crtc_state->dp_tunnel_ref.tunnel)
631-
return;
634+
return 0;
635+
636+
err = drm_dp_tunnel_atomic_set_stream_bw(&state->base,
637+
crtc_state->dp_tunnel_ref.tunnel,
638+
crtc->pipe, 0);
639+
if (err)
640+
return err;
632641

633-
drm_dp_tunnel_atomic_set_stream_bw(&state->base,
634-
crtc_state->dp_tunnel_ref.tunnel,
635-
crtc->pipe, 0);
636642
drm_dp_tunnel_ref_put(&crtc_state->dp_tunnel_ref);
643+
644+
return 0;
637645
}
638646

639647
/**

drivers/gpu/drm/i915/display/intel_dp_tunnel.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ int intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state *state,
4040
struct intel_dp *intel_dp,
4141
const struct intel_connector *connector,
4242
struct intel_crtc_state *crtc_state);
43-
void intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
44-
struct intel_crtc_state *crtc_state);
43+
int intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
44+
struct intel_crtc_state *crtc_state);
4545

4646
int intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state,
4747
struct intel_crtc *crtc);
@@ -88,9 +88,12 @@ intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state *state,
8888
return 0;
8989
}
9090

91-
static inline void
91+
static inline int
9292
intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
93-
struct intel_crtc_state *crtc_state) {}
93+
struct intel_crtc_state *crtc_state)
94+
{
95+
return 0;
96+
}
9497

9598
static inline int
9699
intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state,

0 commit comments

Comments
 (0)