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: rust: add basic serial device bus abstractions
Date: Mon, 16 Mar 2026 12:17:35 +1000	[thread overview]
Message-ID: <review-patch3-20260313-rust_serdev-v3-3-c9a3af214f7f@posteo.de> (raw)
In-Reply-To: <20260313-rust_serdev-v3-3-c9a3af214f7f@posteo.de>

Patch Review

This is the main patch. Several observations:

**1. Timeout::Max maps to 0, which is wrong:**

```rust
+impl Timeout {
+    fn into_jiffies(self) -> isize {
+        match self {
+            ...
+            Self::Max => 0,
+        }
+    }
+}
```

`MAX_SCHEDULE_TIMEOUT` is `LONG_MAX` (i.e., `c_long::MAX`), not 0. A timeout of 0 means "don't wait at all" in `serdev_device_write()`. The `Timeout::Max` variant's doc says "Wait as long as possible" and references `MAX_SCHEDULE_TIMEOUT`, but then passes 0, which is the exact opposite. This should be:

```rust
Self::Max => isize::MAX, // or kernel::task::MAX_SCHEDULE_TIMEOUT
```

**2. Race condition in probe/receive synchronization:**

The `PrivateData` struct uses a `Completion` to synchronize `receive_buf_callback` with probe completion:

```rust
+        private_data.probe_complete.wait_for_completion();
+
+        // SAFETY: No one has exclusive access to `private_data.error`.
+        if unsafe { *private_data.error.get() } {
+            return length;
+        }
```

The `error` field uses `UnsafeCell<bool>` without any synchronization primitive. The SAFETY comment "No one has exclusive access to `private_data.error`" doesn't actually justify the safety — it's the *opposite* of what you'd want. The concern is whether the write to `error` in probe is guaranteed to be visible in `receive_buf_callback` on another thread. The `Completion` itself should provide a memory barrier (via `complete_all`/`wait_for_completion`), so the ordering is likely correct in practice, but this should be documented explicitly. Using an `AtomicBool` would be cleaner and avoid the need for `unsafe` altogether.

**3. `set_baudrate` returns `Result<(), u32>` instead of idiomatic kernel `Result`:**

```rust
+    pub fn set_baudrate(&self, speed: u32) -> Result<(), u32> {
```

Returning the actual baudrate set on failure is useful information, but the `Result<(), u32>` type is non-standard for kernel Rust code. The C function `serdev_device_set_baudrate` returns the actual speed set (which may differ from requested). The sample driver checks `is_err()` and returns `EINVAL`, losing the actual value. Consider either returning `Result<u32>` (the actual speed set) or `Result` with a standard error code.

**4. `write` returns `Result<u32>` but `write_all` returns `Result<usize>` — inconsistent types:**

```rust
+    pub fn write_all(&self, data: &[u8], timeout: Timeout) -> Result<usize> {
...
+    pub fn write(&self, data: &[u8]) -> Result<u32> {
```

Both should consistently use `usize` for byte counts.

**5. The `write` function wraps `serdev_device_write_buf` which returns `ssize_t`:**

```rust
+        let ret =
+            unsafe { bindings::serdev_device_write_buf(self.as_raw(), data.as_ptr(), data.len()) };
+        to_result(ret as i32).map(|()| ret.unsigned_abs())
```

Casting `ssize_t` (which is `isize`/`i64` on 64-bit) to `i32` could truncate positive values. Since this returns the number of bytes written, if `data.len()` > `i32::MAX`, the cast would produce an incorrect error. The same issue exists in `write_all`. Use `ret as i32` carefully — `to_result` expects a C `int`, but the value range should be OK in practice since write buffers won't exceed `i32::MAX`.

**6. `set_baudrate`, `set_flow_control`, `set_parity`, `write`, `write_all`, `write_flush`, `wait_until_sent` are all on `Device<Bound>`, but probe receives `Device<Core>`:**

Looking at the sample driver, `sdev.set_baudrate(...)` is called in `probe` which receives `&Device<Core>`. This compiles because of `impl_device_context_deref` which lets `Device<Core>` deref to `Device<Bound>`. This is the standard pattern, so it's fine.

**7. Typo in doc comments:**

```rust
+    /// Even partiy.
```

Should be "parity".

```rust
+    /// [ Device::wait_until_sent`]
```

Missing `[` — should be `[`Device::wait_until_sent`]`. This appears twice.

**8. The `Kconfig` entry `RUST_SERIAL_DEV_BUS_ABSTRACTIONS` should probably be inside the `if SERIAL_DEV_BUS` block:**

```diff
+config RUST_SERIAL_DEV_BUS_ABSTRACTIONS
+	bool "Rust Serial device bus abstractions"
+	depends on RUST
+	select SERIAL_DEV_BUS
```

It uses `select SERIAL_DEV_BUS` rather than `depends on`, which means enabling the Rust abstractions will force-enable `SERIAL_DEV_BUS`. This is placed *before* `if SERIAL_DEV_BUS`, which is a bit odd. Consider using `depends on SERIAL_DEV_BUS` instead.

**9. `remove_callback` doesn't call `drvdata_obtain` to free the driver data:**

```rust
+    extern "C" fn remove_callback(sdev: *mut bindings::serdev_device) {
+        let sdev = unsafe { &*sdev.cast::<Device<device::CoreInternal>>() };
+        let data = unsafe { sdev.as_ref().drvdata_borrow::<T>() };
+        T::unbind(sdev, data);
+    }
```

It borrows but never takes ownership of the drvdata. The data appears to be freed by devres when the device is released, since `set_drvdata` stores it via `dev_set_drvdata`. But wait — `set_drvdata` stores data via `into_foreign()` and there's no corresponding `from_foreign()` call. The data should be cleaned up by the devres system if `set_drvdata` registers a devres action, but looking at the `device.rs` code, `set_drvdata` does *not* register a devres — it just calls `dev_set_drvdata`. This looks like a **memory leak** — the `Pin<KBox<T>>` stored via `set_drvdata` is never freed. Other bus drivers (platform, etc.) likely call `drvdata_obtain` in their remove callbacks. This needs to be verified.

---
Generated by Claude Code Patch Reviewer

  reply	other threads:[~2026-03-16  2:17 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-13 18:12 [PATCH v3 0/4] rust: add basic serial device bus abstractions Markus Probst
2026-03-13 18:12 ` [PATCH v3 1/4] rust: devres: return reference in `devres::register` Markus Probst
2026-03-16  2:17   ` Claude review: " Claude Code Review Bot
2026-03-13 18:12 ` [PATCH v3 2/4] serdev: add rust private data to serdev_device Markus Probst
2026-03-14  8:07   ` Greg Kroah-Hartman
2026-03-14 11:42     ` Markus Probst
2026-03-14 11:52       ` Greg Kroah-Hartman
2026-03-14 12:08         ` Markus Probst
2026-03-14 13:24           ` Alice Ryhl
2026-03-14 13:31           ` Greg Kroah-Hartman
2026-03-14 13:42             ` Danilo Krummrich
2026-03-14 13:49               ` Markus Probst
2026-03-14 13:54                 ` Danilo Krummrich
2026-03-14 14:58                   ` Markus Probst
2026-03-16  2:17     ` Claude review: " Claude Code Review Bot
2026-03-13 18:12 ` [PATCH v3 3/4] rust: add basic serial device bus abstractions Markus Probst
2026-03-16  2:17   ` Claude Code Review Bot [this message]
2026-03-13 18:12 ` [PATCH v3 4/4] samples: rust: add Rust serial device bus sample device driver Markus Probst
2026-03-16  2:17   ` Claude review: " Claude Code Review Bot
2026-03-16  2:17 ` Claude review: rust: add basic serial device bus abstractions Claude Code Review Bot
  -- strict thread matches above, loose matches on Subject: below --
2026-03-06 19:35 [PATCH v2 0/4] " Markus Probst
2026-03-08 22:21 ` 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-patch3-20260313-rust_serdev-v3-3-c9a3af214f7f@posteo.de \
    --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