Re: Regression with mainline kernel on rpi4

From: Sudip Mukherjee
Date: Wed Sep 22 2021 - 16:19:45 EST


On Wed, Sep 22, 2021 at 7:23 PM Linus Torvalds
<torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
>
> On Wed, Sep 22, 2021 at 10:02 AM Sudip Mukherjee
> <sudipm.mukherjee@xxxxxxxxx> wrote:
> >
> >
> > Attached is a complete dmesg and also the decoded trace.
> > This is done on 4357f03d6611 ("Merge tag 'pm-5.15-rc2' of
> > git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm")
>
> drivers/gpu/drm/vc4/vc4_hdmi.c:1214 is
>
> tmp = (u64)(mode->clock * 1000) * n;
>
> in vc4_hdmi_set_n_cts(), which has apparently been inlined from
> vc4_hdmi_audio_prepare() in vc4_hdmi.c:1398.
>
> So it looks like 'mode' is some offset off a NULL pointer.
>
> Which looks not impossible:
>
> 1207 struct drm_connector *connector = &vc4_hdmi->connector;
> 1208 struct drm_crtc *crtc = connector->state->crtc;
> 1209 const struct drm_display_mode *mode =
> &crtc->state->adjusted_mode;
>
> looks like crtc->state perhaps might be NULL.

I added some debugs to print the addresses, and I am getting:
[ 38.813809] sudip crtc 0000000000000000

This is from struct drm_crtc *crtc = connector->state->crtc;

connector and connector->state had valid addresses.
[ 38.805302] sudip connector ffff000040bac578
[ 38.809779] sudip state ffff000057eb5400

This is the diff of the debug I added:
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 4a1115043114..2a8f06948094 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -1205,11 +1205,20 @@ static void
vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *vc4_hdmi,
static void vc4_hdmi_set_n_cts(struct vc4_hdmi *vc4_hdmi, unsigned
int samplerate)
{
struct drm_connector *connector = &vc4_hdmi->connector;
- struct drm_crtc *crtc = connector->state->crtc;
- const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+ struct drm_crtc *crtc;
+ struct drm_display_mode *mode;
u32 n, cts;
u64 tmp;

+
+ pr_err("sudip connector %px\n", connector);
+ pr_err("sudip state %px\n", connector->state);
+ crtc = connector->state->crtc;
+
+ pr_err("sudip crtc %px\n", crtc);
+ pr_err("sudip state %px\n", crtc->state);
+ pr_err("state mode %px\n", &crtc->state->adjusted_mode);
+ mode = &crtc->state->adjusted_mode;
n = 128 * samplerate / 1000;
tmp = (u64)(mode->clock * 1000) * n;
do_div(tmp, 128 * samplerate);


--
Regards
Sudip