All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jun Nie" <jun.nie@linaro.org>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm/msm/dpu: delete timeout timer when encoder is not busy
Date: Thu, 03 Sep 2026 14:48:26 +0000	[thread overview]
Message-ID: <20260903144827.236AB1F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260903143004.1026181-1-jun.nie@linaro.org>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] A Time-of-Check to Time-of-Use (TOCTOU) race condition in the lockless timer deletion allows an IRQ handler to inadvertently delete the watchdog timer for a newly started frame on another CPU.
- [Medium] The patch fails to address the root cause of the race condition and relies on a subsequent, unrelated IRQ to mask the bug, leaving the original false timeout issue unfixed in many scenarios.

Pre-existing issues:
- [High] Missing synchronization in `dpu_encoder_virt_atomic_disable` allows the driver to disable hardware resources while the timer callback is still executing, leading to crashes.
--

commit 91dd8b2e3a127693bc37ea9250d6d6a4bd503cf0
Author: Jun Nie <jun.nie@linaro.org>

drm/msm/dpu: delete timeout timer when encoder is not busy

This commit attempts to fix a spurious timeout error message during encoder
disable. It adds a check in the frame done IRQ callback to delete the
watchdog timer if the frame busy bits are cleared.

> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 1f20695f81e35..d83d387973311 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -1573,6 +1573,21 @@ void dpu_encoder_frame_done_callback(
>  			| DPU_ENCODER_FRAME_EVENT_PANEL_DEAD)) {
>  
>  		if (!dpu_enc->frame_busy_mask[0]) {
> +			/*
> +			 * dpu_crtc_commit_kickoff calls dpu_encoder_kickoff to
> +			 * mark busy bits, starts the framedone timer next.
> +			 * It is possibile that irq happens between the 2
> +			 * operations. Thus timer is running with busy bits
> +			 * cleared by irq handler and timer will not be deleted
> +			 * anymore. Then false timeout introduces unnecessary
> +			 * confusion and visual defect.
> +			 * delete the timer here to fix it.
> +			 */
> +			if (atomic_read(&dpu_enc->frame_done_timeout_ms)) {
> +				atomic_set(&dpu_enc->frame_done_timeout_ms, 0);
> +				timer_delete(&dpu_enc->frame_done_timer);
> +			}

[Severity: Medium]
Does this patch rely on a subsequent IRQ to fix the false timeout in all
scenarios?

If no subsequent IRQ (like autorefresh or a TE interrupt) fires after the
timer is armed with an empty frame_busy_mask, the timer will expire normally.
When it expires, dpu_encoder_frame_done_timeout() returns early because
frame_busy_mask is empty, but it fails to clear frame_done_timeout_ms:

dpu_encoder_frame_done_timeout() {
    ...
    if (!dpu_enc->frame_busy_mask[0] || !dpu_enc->crtc) {
        return;
    }
    ...
}

Later, dpu_encoder_virt_atomic_disable() checks frame_done_timeout_ms,
finds it non-zero, and still falsely prints the 'timeout pending' error.
Will this leave the bug unfixed for standard operations that do not trigger
extra IRQs?

[Severity: High]
Could this lockless timer deletion introduce a race condition with a new
commit?

CPU1 handling a spurious IRQ in dpu_encoder_frame_done_callback()
evaluates if (!dpu_enc->frame_busy_mask[0]) as true locklessly.

Concurrently, CPU2 starts a new commit:
dpu_encoder_kickoff() sets frame_busy_mask to 1.
dpu_encoder_start_frame_done_timer() arms the timer and sets
frame_done_timeout_ms to 500.

CPU1 continues execution, reads frame_done_timeout_ms (now 500 from CPU2),
sets it to 0, and calls timer_delete().

Does this silently delete the newly armed watchdog timer for CPU2's commit,
leaving it without watchdog protection if the hardware hangs?

[Severity: High]
This is a pre-existing issue, but does dpu_encoder_virt_atomic_disable()
lack synchronization when disabling hardware resources?

dpu_encoder_frame_done_timeout() clears frame_done_timeout_ms via
atomic_xchg() early in its execution:

dpu_encoder_frame_done_timeout() {
    ...
    } else if (!atomic_xchg(&dpu_enc->frame_done_timeout_ms, 0)) {
        return;
    }
    ...
}

If dpu_encoder_virt_atomic_disable() runs concurrently, it checks:

    if (atomic_xchg(&dpu_enc->frame_done_timeout_ms, 0)) {
        timer_delete_sync(&dpu_enc->frame_done_timer);
    }

If the timeout callback has already cleared the variable, the disable path
sees 0, skips timer_delete_sync(), and proceeds to disable clocks and power
domains. Meanwhile, the timeout callback is still executing and accesses
hardware registers, which can cause a synchronous external abort when clocks
are disabled. Should this path always synchronize with the timer callback?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260903143004.1026181-1-jun.nie@linaro.org?part=1

      parent reply	other threads:[~2026-09-03 14:48 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-03 14:29 [PATCH] drm/msm/dpu: delete timeout timer when encoder is not busy Jun Nie
2026-09-03 14:39 ` Jun Nie
2026-09-13 22:35   ` Dmitry Baryshkov
2026-09-03 14:48 ` sashiko-bot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260903144827.236AB1F00A3A@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jun.nie@linaro.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.