lkml.org 
[lkml]   [2022]   [Jun]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 125/411] drm/msm/mdp5: Return error code in mdp5_mixer_release when deadlock is detected
    Date
    From: Jessica Zhang <quic_jesszhan@quicinc.com>

    [ Upstream commit ca75f6f7c6f89365e40f10f641b15981b1f07c31 ]

    There is a possibility for mdp5_get_global_state to return
    -EDEADLK when acquiring the modeset lock, but currently global_state in
    mdp5_mixer_release doesn't check for if an error is returned.

    To avoid a NULL dereference error, let's have mdp5_mixer_release
    check if an error is returned and propagate that error.

    Reported-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
    Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
    Fixes: 7907a0d77cb4 ("drm/msm/mdp5: Use the new private_obj state")
    Reviewed-by: Rob Clark <robdclark@gmail.com>
    Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
    Patchwork: https://patchwork.freedesktop.org/patch/485181/
    Link: https://lore.kernel.org/r/20220505214051.155-2-quic_jesszhan@quicinc.com
    Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 10 ++++++++--
    drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c | 15 +++++++++++----
    drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h | 4 ++--
    3 files changed, 21 insertions(+), 8 deletions(-)

    diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
    index 395146884a22..9afbce3cb87b 100644
    --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
    +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
    @@ -534,9 +534,15 @@ int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc,
    if (ret)
    return ret;

    - mdp5_mixer_release(new_crtc_state->state, old_mixer);
    + ret = mdp5_mixer_release(new_crtc_state->state, old_mixer);
    + if (ret)
    + return ret;
    +
    if (old_r_mixer) {
    - mdp5_mixer_release(new_crtc_state->state, old_r_mixer);
    + ret = mdp5_mixer_release(new_crtc_state->state, old_r_mixer);
    + if (ret)
    + return ret;
    +
    if (!need_right_mixer)
    pipeline->r_mixer = NULL;
    }
    diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c
    index 954db683ae44..2536def2a000 100644
    --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c
    +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c
    @@ -116,21 +116,28 @@ int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc,
    return 0;
    }

    -void mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer)
    +int mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer)
    {
    struct mdp5_global_state *global_state = mdp5_get_global_state(s);
    - struct mdp5_hw_mixer_state *new_state = &global_state->hwmixer;
    + struct mdp5_hw_mixer_state *new_state;

    if (!mixer)
    - return;
    + return 0;
    +
    + if (IS_ERR(global_state))
    + return PTR_ERR(global_state);
    +
    + new_state = &global_state->hwmixer;

    if (WARN_ON(!new_state->hwmixer_to_crtc[mixer->idx]))
    - return;
    + return -EINVAL;

    DBG("%s: release from crtc %s", mixer->name,
    new_state->hwmixer_to_crtc[mixer->idx]->name);

    new_state->hwmixer_to_crtc[mixer->idx] = NULL;
    +
    + return 0;
    }

    void mdp5_mixer_destroy(struct mdp5_hw_mixer *mixer)
    diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h
    index 43c9ba43ce18..545ee223b9d7 100644
    --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h
    +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h
    @@ -30,7 +30,7 @@ void mdp5_mixer_destroy(struct mdp5_hw_mixer *lm);
    int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc,
    uint32_t caps, struct mdp5_hw_mixer **mixer,
    struct mdp5_hw_mixer **r_mixer);
    -void mdp5_mixer_release(struct drm_atomic_state *s,
    - struct mdp5_hw_mixer *mixer);
    +int mdp5_mixer_release(struct drm_atomic_state *s,
    + struct mdp5_hw_mixer *mixer);

    #endif /* __MDP5_LM_H__ */
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-06-13 13:22    [W:4.722 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site