All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Mike Lothian" <mike@fireburn.co.uk>
Cc: dri-devel@lists.freedesktop.org, ojeda@kernel.org
Subject: Re: [PATCH v3 8/13] drm/vino: add the KMS device and the atomic path
Date: Wed, 26 Aug 2026 16:59:31 +0000	[thread overview]
Message-ID: <20260826165931.B63521F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260826163913.7052-9-mike@fireburn.co.uk>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Operations that sleep (Mutex locks, GFP_KERNEL allocations, and vmap) and long synchronous memory copies are performed within DRM atomic commit callbacks.
- [High] Page flips are permanently lost if an older frame is still pending, causing the screen to freeze on stale frames.
- [High] atomic_check reads shared global state without global atomic tracking, allowing concurrent commits to overcommit the dock's pixel bandwidth.
--

commit b222a22b8b0ea906ee63e26872096f97f4fb7ece
Author: Mike Lothian <mike@fireburn.co.uk>
drm/vino: add the KMS device and the atomic path

This commit adds the KMS side of the sink, including the DRM driver, GEM
and file types, CRTCs, planes, and connectors. It introduces atomic
callbacks to record desired state and workers to handle scanout, formatting,
and KMS limits checking.

> diff --git a/drivers/gpu/drm/vino/drm_sink.rs b/drivers/gpu/drm/vino/drm_sink.rs
> index 0000000000000..86708db89699a
> --- /dev/null
> +++ b/drivers/gpu/drm/vino/drm_sink.rs
[ ... ]
> +    fn get(
> +        &mut self,
> +        fb: &kms::framebuffer::Framebuffer<VinoDrmDriver>,
> +    ) -> Result<Arc<SourceBinding>> {
[ ... ]
> +        let binding = Arc::new(
> +            SourceBinding {
> +                framebuffer: ARef::from(fb),
> +                mapping: fb.owned_vmap::<VinoObject>()?,
> +            },
> +            GFP_KERNEL,
> +        )?;

[Severity: High]
Does this code sleep in an atomic context?

DRM CRTC and plane atomic callbacks execute in an atomic context during
non-blocking commits, where sleeping is strictly forbidden. This performs
a GFP_KERNEL allocation and maps memory with fb.owned_vmap(), both of
which can sleep.

> diff --git a/drivers/gpu/drm/vino/drm_sink/dispatch.rs b/drivers/gpu/drm/vino/drm_sink/dispatch.rs
> index 0000000000000..bd759ad4bc992
> --- /dev/null
> +++ b/drivers/gpu/drm/vino/drm_sink/dispatch.rs
[ ... ]
> +    pub(super) fn queue_scanout(
> +        &self,
> +        dev: &VinoDrmDevice,
> +        fb: &kms::framebuffer::Framebuffer<VinoDrmDriver>,
> +        mut frame: PendingScanout,
> +    ) {
[ ... ]
> +        let coalesce = {
> +            let pending = self.pending_scanout.lock();
> +            pending[connector].as_ref().is_some_and(|queued| {
> +                queued.w == frame.w
> +                    && queued.h == frame.h
> +                    && queued.rotation == frame.rotation
> +                    && self.keyframe_pending.load(Ordering::Acquire) & (1u32 << connector) == 0
> +            })
> +        };
> +        if coalesce {
> +            vino_debug!("vino: socket {socket} flip coalesced before snapshot\n");
> +            return;
> +        }

[Severity: High]
Can this early return cause the display to permanently freeze on stale frames?

If pending[connector] contains an unclaimed frame (making coalesce true),
this discards the new frame before taking a snapshot. The scanout worker
will only encode and scan out the older pending frame. If the compositor
goes idle and stops submitting frames, the worker will repeatedly process
the old frame and arm the settle_repaint timer with it, losing the most
recent updates.

[ ... ]
> +        let (mut surface, binding, idx) = {
> +            let mut pool = self.shadow[connector].lock();

[Severity: High]
Could this Mutex lock cause a deadlock or panic when called from the
atomic commit path?

This acquires a sleeping Mutex (shadow.lock()), which is unsafe in
atomic context.

[ ... ]
> +        let r = snapshot_to_shadow(
> +            self.geometry(),
> +            &mut surface,
> +            &binding.mapping,
> +            source_w,
> +            source_h,
> +        );

[Severity: High]
Is it safe to perform a synchronous memory copy of up to 14.7 MB here?

Executing a long synchronous memory copy in the non-blocking atomic
commit callback can lead to system instability, as atomic contexts
should be kept as short as possible.

> diff --git a/drivers/gpu/drm/vino/drm_sink/limits.rs b/drivers/gpu/drm/vino/drm_sink/limits.rs
> index 0000000000000..96d2d8dcf8c29
> --- /dev/null
> +++ b/drivers/gpu/drm/vino/drm_sink/limits.rs
[ ... ]
> +    pub(super) fn other_connectors_rate(
> +        &self,
> +        state: &kernel::drm::kms::atomic::AtomicStateMutator<VinoDrmDriver>,
> +        connector: usize,
> +    ) -> u32 {
[ ... ]
> +        let timings = *self.last_timing.lock();
> +        let mut total: u32 = 0;
> +        for (i, t) in timings.iter().enumerate() {
> +            if i == connector {
> +                continue;
> +            }

[Severity: High]
Does reading shared global state here without global DRM atomic tracking
allow concurrent commits to overcommit the dock's pixel bandwidth?

Because this state is protected only by a local spinlock rather than being
part of the global DRM atomic state machine (e.g., via a drm_private_obj),
concurrent commits to different connectors will not serialize against each
other. Each commit will see the other connector's old bandwidth and succeed,
potentially bypassing hardware limits and causing a blank display.

> diff --git a/drivers/gpu/drm/vino/drm_sink/mode_objects.rs b/drivers/gpu/drm/vino/drm_sink/mode_objects.rs
> index 0000000000000..d3ec818ec1daa
> --- /dev/null
> +++ b/drivers/gpu/drm/vino/drm_sink/mode_objects.rs
[ ... ]
> +    fn atomic_check(check: CrtcAtomicCheck<'_, Self>) -> Result {
[ ... ]
> +        let others = data.other_connectors_rate(&state, connector);
> +        let combined = new_rate.saturating_add(others);

[Severity: High]
Could this call read a stale bandwidth value from other connectors?

As noted in limits.rs, this reads shared global state without global
atomic tracking, which might allow concurrent commits to overcommit
the display bandwidth.

[ ... ]
> +    fn atomic_update(commit: PlaneAtomicCommit<'_, Self>) {
[ ... ]
> +        data.queue_scanout(
> +            dev,
> +            fb,
> +            PendingScanout {
> +                connector,
> +                rotation,
> +                clips,
> +                nclips,
> +                w,
> +                h,
> +                shadow_idx: 0,
> +                shadow_generation: 0,
> +            },
> +        );
> +    }

[Severity: High]
Does calling queue_scanout() from this atomic callback invoke operations
that are unsafe in atomic context?

VinoPlane::atomic_update() executes in an atomic context during
non-blocking commits. However, queue_scanout() acquires a sleeping
Mutex, allocates with GFP_KERNEL, maps memory, and performs large
synchronous memory copies.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260826163913.7052-1-mike@fireburn.co.uk?part=8

  reply	other threads:[~2026-08-26 16:59 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-26 16:37 [PATCH v3 0/13] drm/vino: a Rust driver for DisplayLink DL3 docks Mike Lothian
2026-08-26 16:37 ` [PATCH v3 1/13] drm/vino: add the DL3 wire framing Mike Lothian
2026-08-26 16:37 ` [PATCH v3 2/13] drm/vino: add the USB transport Mike Lothian
2026-08-26 16:58   ` sashiko-bot
2026-08-26 16:37 ` [PATCH v3 3/13] drm/vino: add the crypto primitives and the HDCP 2.2 AKE Mike Lothian
2026-08-26 16:37 ` [PATCH v3 4/13] drm/vino: add the encrypted control plane Mike Lothian
2026-08-26 16:37 ` [PATCH v3 5/13] drm/vino: add the dock profiles Mike Lothian
2026-08-26 16:37 ` [PATCH v3 6/13] drm/vino: add the video codec Mike Lothian
2026-08-26 16:56   ` sashiko-bot
2026-08-26 16:37 ` [PATCH v3 7/13] drm/vino: add control-session bring-up Mike Lothian
2026-08-26 16:57   ` sashiko-bot
2026-08-26 16:37 ` [PATCH v3 8/13] drm/vino: add the KMS device and the atomic path Mike Lothian
2026-08-26 16:59   ` sashiko-bot [this message]
2026-08-26 16:37 ` [PATCH v3 9/13] drm/vino: add the dock activation and scanout path Mike Lothian
2026-08-26 16:59   ` sashiko-bot
2026-08-26 16:37 ` [PATCH v3 10/13] drm/vino: read the dock's firmware version, and update it over DFU Mike Lothian
2026-08-26 16:58   ` sashiko-bot
2026-08-26 16:37 ` [PATCH v3 11/13] drm/vino: add the USB driver frontend Mike Lothian
2026-08-26 17:01   ` sashiko-bot
2026-08-26 16:37 ` [PATCH v3 12/13] drm/vino: allow the driver to be built Mike Lothian
2026-08-26 17:04   ` sashiko-bot
2026-08-26 16:37 ` [PATCH v3 13/13] Documentation/gpu: document the Vino driver Mike Lothian
2026-08-26 17:10   ` sashiko-bot
2026-08-26 17:28   ` Randy Dunlap

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=20260826165931.B63521F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=mike@fireburn.co.uk \
    --cc=ojeda@kernel.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.