From: "Danilo Krummrich" <dakr@kernel.org>
To: "Uwe Kleine-König" <ukleinek@kernel.org>
Cc: "Michal Wilczynski" <m.wilczynski@samsung.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>, "Guo Ren" <guoren@kernel.org>,
"Fu Wei" <wefu@redhat.com>, "Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Paul Walmsley" <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Albert Ou" <aou@eecs.berkeley.edu>,
"Alexandre Ghiti" <alex@ghiti.fr>,
"Marek Szyprowski" <m.szyprowski@samsung.com>,
"Benno Lossin" <lossin@kernel.org>,
"Michael Turquette" <mturquette@baylibre.com>,
"Drew Fustini" <fustini@kernel.org>,
linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org,
rust-for-linux@vger.kernel.org, linux-riscv@lists.infradead.org,
devicetree@vger.kernel.org,
"Krzysztof Kozlowski" <krzysztof.kozlowski@linaro.org>
Subject: Re: [PATCH v10 0/7] Rust Abstractions for PWM subsystem with TH1520 PWM driver
Date: Thu, 10 Jul 2025 23:19:24 +0200 [thread overview]
Message-ID: <DB8OT5ZZ4SRO.WP5PBFLML683@kernel.org> (raw)
In-Reply-To: <cbxpqormchajfcnf7xxopd7j7igriqus4cuu5jfvxb3mbfb5tu@qz4rc67vjyif>
On Thu Jul 10, 2025 at 10:57 PM CEST, Uwe Kleine-König wrote:
> On Thu, Jul 10, 2025 at 06:06:26PM +0200, Danilo Krummrich wrote:
>> On Thu Jul 10, 2025 at 5:25 PM CEST, Uwe Kleine-König wrote:
>> > Hello Michal,
>> >
>> > On Thu, Jul 10, 2025 at 03:48:08PM +0200, Michal Wilczynski wrote:
>> >> On 7/10/25 15:10, Uwe Kleine-König wrote:
>> >> > On Thu, Jul 10, 2025 at 10:42:07AM +0200, Michal Wilczynski wrote:
>> >> >> On 7/7/25 11:48, Michal Wilczynski wrote:
>> >> >>> The series is structured as follows:
>> >> >>> - Expose static function pwmchip_release.
>> >> >
>> >> > Is this really necessary? I didn't try to understand the requirements
>> >> > yet, but I wonder about that. If you get the pwmchip from
>> >> > __pwmchip_add() the right thing to do to release it is to call
>> >> > pwmchip_remove(). Feels like a layer violation.
>> >>
>> >> It's required to prevent a memory leak in a specific, critical failure
>> >> scenario. The sequence of events is as follows:
>> >>
>> >> pwm::Chip::new() succeeds, allocating both the C struct pwm_chip and
>> >> the Rust drvdata.
>> >>
>> >> pwm::Registration::register() (which calls pwmchip_add()) fails for
>> >> some reason.
>> >
>>
>> (Just trying to help clear up the confusion.)
>
> Very appreciated!
>
>> > If you called pwmchip_alloc() but not yet pwmchip_add(), the right
>> > function to call for cleanup is pwmchip_put().
>>
>> That is exactly what is happening when ARef<Chip> is dropped. If the reference
>> count drops to zero, pwmchip_release() is called, which frees the chip. However,
>> this would leave the driver's private data allocation behind, which is owned by
>> the Chip instance.
>
> I don't understand that. The chip and the driver private data both are
> located in the same allocation. How is this a problem of the driver
> private data only then? The kfree() in pwmchip_release() is good enough
> for both?!
Not in the current abstractions, there are two allocations, one for the Chip and
one for the driver's private data, or in other words the abstraction uses
pwmchip_set_drvdata() and pwmchip_get_drvdata().
Having a brief look at pwmchip_alloc(), it seems to me that PWM supports the
subclassing pattern with pwmchip_priv().
We should probably take advantage of that. Assuming we do that, the Rust
abstraction still needs a release() callback because we still need to call
drop_in_place() in order to get the destructor of the driver's private data
type called. We actually missed this in DRM and I fixed it up recently [1].
@Michal: With the subclassing pattern the Chip structure would look like this:
#[repr(C)]
#[pin_data]
pub struct Chip<T> {
inner: Opaque<bindings::pwm_chip>,
#[pin]
data: T,
}
And in the release() callback would look like this:
extern "C" fn release(ptr: *mut bindings::pwm_chip) {
// CAST: Casting `ptr` to `Chip<T>` is valid, since [...].
let this = ptr.cast<Chip<T>>();
// SAFETY:
// - When `release` runs it is guaranteed that there is no further access to `this`.
// - `this` is valid for dropping.
unsafe { core::ptr::drop_in_place(this) };
}
This is exactly what we're doing in DRM as well, I would have recommended this
to begin with, but I didn't recognize that PWM supports subclassing. :)
I recommend having a look at [2].
[1] https://lore.kernel.org/all/20250629153747.72536-1-dakr@kernel.org/
[2] https://gitlab.freedesktop.org/drm/misc/kernel/-/blob/drm-misc-fixes/rust/kernel/drm/device.rs
WARNING: multiple messages have this Message-ID (diff)
From: "Danilo Krummrich" <dakr@kernel.org>
To: "Uwe Kleine-König" <ukleinek@kernel.org>
Cc: "Michal Wilczynski" <m.wilczynski@samsung.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>, "Guo Ren" <guoren@kernel.org>,
"Fu Wei" <wefu@redhat.com>, "Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Paul Walmsley" <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Albert Ou" <aou@eecs.berkeley.edu>,
"Alexandre Ghiti" <alex@ghiti.fr>,
"Marek Szyprowski" <m.szyprowski@samsung.com>,
"Benno Lossin" <lossin@kernel.org>,
"Michael Turquette" <mturquette@baylibre.com>,
"Drew Fustini" <fustini@kernel.org>,
linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org,
rust-for-linux@vger.kernel.org, linux-riscv@lists.infradead.org,
devicetree@vger.kernel.org,
"Krzysztof Kozlowski" <krzysztof.kozlowski@linaro.org>
Subject: Re: [PATCH v10 0/7] Rust Abstractions for PWM subsystem with TH1520 PWM driver
Date: Thu, 10 Jul 2025 23:19:24 +0200 [thread overview]
Message-ID: <DB8OT5ZZ4SRO.WP5PBFLML683@kernel.org> (raw)
In-Reply-To: <cbxpqormchajfcnf7xxopd7j7igriqus4cuu5jfvxb3mbfb5tu@qz4rc67vjyif>
On Thu Jul 10, 2025 at 10:57 PM CEST, Uwe Kleine-König wrote:
> On Thu, Jul 10, 2025 at 06:06:26PM +0200, Danilo Krummrich wrote:
>> On Thu Jul 10, 2025 at 5:25 PM CEST, Uwe Kleine-König wrote:
>> > Hello Michal,
>> >
>> > On Thu, Jul 10, 2025 at 03:48:08PM +0200, Michal Wilczynski wrote:
>> >> On 7/10/25 15:10, Uwe Kleine-König wrote:
>> >> > On Thu, Jul 10, 2025 at 10:42:07AM +0200, Michal Wilczynski wrote:
>> >> >> On 7/7/25 11:48, Michal Wilczynski wrote:
>> >> >>> The series is structured as follows:
>> >> >>> - Expose static function pwmchip_release.
>> >> >
>> >> > Is this really necessary? I didn't try to understand the requirements
>> >> > yet, but I wonder about that. If you get the pwmchip from
>> >> > __pwmchip_add() the right thing to do to release it is to call
>> >> > pwmchip_remove(). Feels like a layer violation.
>> >>
>> >> It's required to prevent a memory leak in a specific, critical failure
>> >> scenario. The sequence of events is as follows:
>> >>
>> >> pwm::Chip::new() succeeds, allocating both the C struct pwm_chip and
>> >> the Rust drvdata.
>> >>
>> >> pwm::Registration::register() (which calls pwmchip_add()) fails for
>> >> some reason.
>> >
>>
>> (Just trying to help clear up the confusion.)
>
> Very appreciated!
>
>> > If you called pwmchip_alloc() but not yet pwmchip_add(), the right
>> > function to call for cleanup is pwmchip_put().
>>
>> That is exactly what is happening when ARef<Chip> is dropped. If the reference
>> count drops to zero, pwmchip_release() is called, which frees the chip. However,
>> this would leave the driver's private data allocation behind, which is owned by
>> the Chip instance.
>
> I don't understand that. The chip and the driver private data both are
> located in the same allocation. How is this a problem of the driver
> private data only then? The kfree() in pwmchip_release() is good enough
> for both?!
Not in the current abstractions, there are two allocations, one for the Chip and
one for the driver's private data, or in other words the abstraction uses
pwmchip_set_drvdata() and pwmchip_get_drvdata().
Having a brief look at pwmchip_alloc(), it seems to me that PWM supports the
subclassing pattern with pwmchip_priv().
We should probably take advantage of that. Assuming we do that, the Rust
abstraction still needs a release() callback because we still need to call
drop_in_place() in order to get the destructor of the driver's private data
type called. We actually missed this in DRM and I fixed it up recently [1].
@Michal: With the subclassing pattern the Chip structure would look like this:
#[repr(C)]
#[pin_data]
pub struct Chip<T> {
inner: Opaque<bindings::pwm_chip>,
#[pin]
data: T,
}
And in the release() callback would look like this:
extern "C" fn release(ptr: *mut bindings::pwm_chip) {
// CAST: Casting `ptr` to `Chip<T>` is valid, since [...].
let this = ptr.cast<Chip<T>>();
// SAFETY:
// - When `release` runs it is guaranteed that there is no further access to `this`.
// - `this` is valid for dropping.
unsafe { core::ptr::drop_in_place(this) };
}
This is exactly what we're doing in DRM as well, I would have recommended this
to begin with, but I didn't recognize that PWM supports subclassing. :)
I recommend having a look at [2].
[1] https://lore.kernel.org/all/20250629153747.72536-1-dakr@kernel.org/
[2] https://gitlab.freedesktop.org/drm/misc/kernel/-/blob/drm-misc-fixes/rust/kernel/drm/device.rs
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2025-07-10 21:19 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20250707094926eucas1p155bd967b6986c4a999776839b1aa1fc6@eucas1p1.samsung.com>
2025-07-07 9:48 ` [PATCH v10 0/7] Rust Abstractions for PWM subsystem with TH1520 PWM driver Michal Wilczynski
2025-07-07 9:48 ` Michal Wilczynski
2025-07-07 9:48 ` [PATCH v10 1/7] pwm: Export `pwmchip_release` for external use Michal Wilczynski
2025-07-07 9:48 ` Michal Wilczynski
2025-07-07 9:48 ` [PATCH v10 2/7] rust: pwm: Add Kconfig and basic data structures Michal Wilczynski
2025-07-07 9:48 ` Michal Wilczynski
2025-07-07 9:48 ` [PATCH v10 3/7] rust: pwm: Add complete abstraction layer Michal Wilczynski
2025-07-07 9:48 ` Michal Wilczynski
2025-07-07 9:48 ` [PATCH v10 4/7] pwm: Add Rust driver for T-HEAD TH1520 SoC Michal Wilczynski
2025-07-07 9:48 ` Michal Wilczynski
2025-07-07 9:48 ` [PATCH v10 5/7] dt-bindings: pwm: thead: Add T-HEAD TH1520 PWM controller Michal Wilczynski
2025-07-07 9:48 ` Michal Wilczynski
2025-07-07 9:48 ` [PATCH v10 6/7] riscv: dts: thead: Add PWM controller node Michal Wilczynski
2025-07-07 9:48 ` Michal Wilczynski
2025-07-07 9:48 ` [PATCH v10 7/7] riscv: dts: thead: Add PWM fan and thermal control Michal Wilczynski
2025-07-07 9:48 ` Michal Wilczynski
2025-07-10 8:42 ` [PATCH v10 0/7] Rust Abstractions for PWM subsystem with TH1520 PWM driver Michal Wilczynski
2025-07-10 8:42 ` Michal Wilczynski
2025-07-10 10:17 ` Danilo Krummrich
2025-07-10 10:17 ` Danilo Krummrich
2025-07-10 10:29 ` Michal Wilczynski
2025-07-10 10:29 ` Michal Wilczynski
2025-07-10 13:36 ` Uwe Kleine-König
2025-07-10 13:36 ` Uwe Kleine-König
2025-07-10 13:41 ` Danilo Krummrich
2025-07-10 13:41 ` Danilo Krummrich
2025-07-10 13:10 ` Uwe Kleine-König
2025-07-10 13:10 ` Uwe Kleine-König
2025-07-10 13:48 ` Michal Wilczynski
2025-07-10 13:48 ` Michal Wilczynski
2025-07-10 15:25 ` Uwe Kleine-König
2025-07-10 15:25 ` Uwe Kleine-König
2025-07-10 16:06 ` Danilo Krummrich
2025-07-10 16:06 ` Danilo Krummrich
2025-07-10 20:57 ` Uwe Kleine-König
2025-07-10 20:57 ` Uwe Kleine-König
2025-07-10 21:19 ` Danilo Krummrich [this message]
2025-07-10 21:19 ` Danilo Krummrich
2025-07-11 12:36 ` Michal Wilczynski
2025-07-11 12:36 ` Michal Wilczynski
2025-07-10 16:58 ` Michal Wilczynski
2025-07-10 16:58 ` Michal Wilczynski
2025-07-10 20:39 ` Uwe Kleine-König
2025-07-10 20:39 ` Uwe Kleine-König
2025-07-11 15:19 ` Michal Wilczynski
2025-07-11 15:19 ` Michal Wilczynski
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=DB8OT5ZZ4SRO.WP5PBFLML683@kernel.org \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=alex@ghiti.fr \
--cc=aliceryhl@google.com \
--cc=aou@eecs.berkeley.edu \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=fustini@kernel.org \
--cc=gary@garyguo.net \
--cc=guoren@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=krzysztof.kozlowski@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pwm@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=lossin@kernel.org \
--cc=m.szyprowski@samsung.com \
--cc=m.wilczynski@samsung.com \
--cc=mturquette@baylibre.com \
--cc=ojeda@kernel.org \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=robh@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
--cc=ukleinek@kernel.org \
--cc=wefu@redhat.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 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.