public inbox for drm-ai-reviews@public-inbox.freedesktop.org
 help / color / mirror / Atom feed
From: Claude Code Review Bot <claude-review@example.com>
To: dri-devel-reviews@example.com
Subject: Claude review: drm/vblank: Introduce deferred vblank enable/disable
Date: Wed, 25 Mar 2026 07:22:01 +1000	[thread overview]
Message-ID: <review-patch2-20260323202755.315929-3-sunpeng.li@amd.com> (raw)
In-Reply-To: <20260323202755.315929-3-sunpeng.li@amd.com>

Patch Review

This is the core patch and has the most issues:

**1. Workqueue allocated unconditionally (wasteful)**

```c
dev->deferred_vblank_wq = alloc_workqueue("drm_vblank_deferred_wq",
                                          WQ_HIGHPRI | WQ_UNBOUND,
                                          0);
```

This allocates a workqueue for *every* DRM device regardless of whether any CRTC uses deferred vblank. This wastes resources for the vast majority of drivers. Consider lazily allocating it (e.g., in `drm_crtc_init_with_planes` when the funcs have deferred callbacks) or at least guarding it behind a check.

**2. Race between deferred enable and drm_crtc_vblank_off()**

`drm_vblank_get()` queues the enable worker, then releases `vbl_lock`. If `drm_crtc_vblank_off()` runs before the worker executes, the worker will call `drm_vblank_enable()` → `crtc->funcs->enable_vblank()` on hardware that's being torn down. The worker does:

```c
spin_lock_irqsave(&dev->vbl_lock, irqflags);
ret = drm_vblank_enable(dev, vblank->pipe);
```

But `drm_crtc_vblank_off()` sets `vblank->inmodeset` under `vbl_lock`, which would make `drm_vblank_enable()` fail with `-EINVAL` (because the refcount was already decremented by `vblank_off`). However, the `pre_enable_vblank()` callback runs *before* this lock is taken, so the driver's blocking pre-work could still execute against torn-down hardware. Consider cancelling pending enable work in `drm_crtc_vblank_off()` before proceeding, or checking `vblank->inmodeset` inside the worker before calling the pre-hook.

**3. Race between deferred disable and deferred enable**

If a deferred disable is pending (delayed work) and a new `drm_vblank_get()` triggers a deferred enable, the pending disable isn't cancelled. The `queue_work()` for enable is non-delayed, so it may execute first, but there's no explicit cancellation of the pending `disable_work`. After enable completes, the stale disable could fire. The regular (non-deferred) path handles this via the `disable_timer` being re-armed, but the deferred path should cancel `disable_work` when queueing `enable_work`.

**4. drm_wait_vblank_ioctl ordering bug**

```c
ret = drm_vblank_get(dev, pipe);
drm_crtc_vblank_wait_deferred_enable(drm_crtc_from_index(dev, pipe));

if (ret) {
```

The `drm_crtc_vblank_wait_deferred_enable()` is called *before* checking `ret`. If `drm_vblank_get()` returned an error, this waits on a potentially stale/completed completion. It should be inside the success path:

```c
ret = drm_vblank_get(dev, pipe);
if (ret) {
    ...error handling...
}
drm_crtc_vblank_wait_deferred_enable(drm_crtc_from_index(dev, pipe));
```

**5. Missing `cancel_work_sync` / `cancel_delayed_work_sync` in cleanup paths**

In `drm_dev_init_release()`, only `flush_workqueue` + `destroy_workqueue` is done. But `drm_vblank_init_release()` (per-CRTC cleanup via `timer_delete_sync`) doesn't cancel the per-CRTC `enable_work` and `disable_work`. These should be cancelled in `drm_vblank_init_release()`:

```c
cancel_work_sync(&vblank->enable_work);
cancel_delayed_work_sync(&vblank->disable_work);
```

**6. `try_wait_for_completion` used outside lock for racy check**

```c
bool deferred_enable_pending =
    needs_deferred_enable &&
    !try_wait_for_completion(&vblank->enable_done);
```

`try_wait_for_completion()` actually *consumes* the completion if it's done. Inside `drm_vblank_get()` under `vbl_lock`, this consumption could cause a subsequent `wait_for_completion_timeout` (from `drm_crtc_vblank_wait_deferred_enable`) to block even though enable already completed. Using `completion_done()` instead would be non-destructive.

**7. `WQ_UNBOUND` with `max_active=0`**

The workqueue is created with `WQ_UNBOUND` and `max_active=0` (unlimited). The commit message says "single-threaded worker" but the workqueue is not single-threaded. Enable and disable workers for different CRTCs (or even the same CRTC) could run concurrently. If single-threaded semantics are intended, use `alloc_ordered_workqueue()`.

---
Generated by Claude Code Patch Reviewer

  reply	other threads:[~2026-03-24 21:22 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-23 20:27 [PATCH v2 0/5] drm/vblank: Deferred Enable and Disable sunpeng.li
2026-03-23 20:27 ` [PATCH v2 1/5] drm/vblank: Add drm_crtc_vblank_is_off() helper sunpeng.li
2026-03-24 20:20   ` Mario Limonciello
2026-03-24 21:22   ` Claude review: " Claude Code Review Bot
2026-03-23 20:27 ` [PATCH v2 2/5] drm/vblank: Introduce deferred vblank enable/disable sunpeng.li
2026-03-24 21:22   ` Claude Code Review Bot [this message]
2026-03-23 20:27 ` [PATCH v2 3/5] drm/amd/display: Refactor amdgpu_dm_crtc_set_vblank sunpeng.li
2026-03-24 21:22   ` Claude review: " Claude Code Review Bot
2026-03-23 20:27 ` [PATCH v2 4/5] drm/amd/display: Implement deferred vblanks on IPS platforms sunpeng.li
2026-03-24 21:22   ` Claude review: " Claude Code Review Bot
2026-03-23 20:27 ` [PATCH v2 5/5] drm/vblank: Add some debugging trace events sunpeng.li
2026-03-24 21:22   ` Claude review: " Claude Code Review Bot
2026-03-24 21:22 ` Claude review: drm/vblank: Deferred Enable and Disable Claude Code Review Bot
  -- strict thread matches above, loose matches on Subject: below --
2026-02-24 21:26 [PATCH 0/5] " sunpeng.li
2026-02-24 21:26 ` [PATCH 2/5] drm/vblank: Introduce deferred vblank enable/disable sunpeng.li
2026-02-27  4:40   ` Claude review: " Claude Code Review Bot

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=review-patch2-20260323202755.315929-3-sunpeng.li@amd.com \
    --to=claude-review@example.com \
    --cc=dri-devel-reviews@example.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox