Re: [RFC PATCH 7/8] rust: add firmware abstractions

2024-06-07 Thread FUJITA Tomonori
On Fri, 7 Jun 2024 19:55:49 +0200
Danilo Krummrich  wrote:

> On Fri, Jun 07, 2024 at 05:41:11PM +0200, Greg KH wrote:
>> On Fri, Jun 07, 2024 at 03:33:39PM +0200, Danilo Krummrich wrote:
>> > On Fri, Jun 07, 2024 at 02:36:50PM +0200, Greg KH wrote:
>> > > Anyway, that's all hand-wavy right now, sorry, to get back to the point
>> > > here, again, let's take this, which will allow the firmware bindings to
>> > > be resubmitted and hopefully accepted, and we can move forward from
>> > > there to "real" things like a USB or PCI or even platform device and
>> > > driver binding stuff.
>> > 
>> > In order to continue I propose to send out the following series:
>> > 
>> > 1) minimal device and firmware abstractions only
>> 
>> Sounds good.
> 
> Just a heads-up, I'll probably send this one quite a bit earlier than the 
> other
> two to make sure to unblock Fujita on their PHY driver.

Please. The sooner, the better. I need to send the PHY driver with
these patchse to netdev.

I'm not sure what the above "minimal device" means. If you send the
original patch again instead of the patch that Greg already approved
and the discussion continues, then I proceed with the approved patch.


Re: [RFC PATCH 7/8] rust: add firmware abstractions

2024-06-07 Thread FUJITA Tomonori
Hi,

On Fri, 31 May 2024 11:59:47 +0200
Danilo Krummrich  wrote:

> Once we get to a conclusion I can send a series with only the device and 
> firmare
> abstractions such that we can get them in outside of the scope of the reset of
> both series to get your driver going.

Since your discussion with Greg seems to continue for a while, let me
include the following patch that Greg approved with the next version
of the PHY driver patchset.

You have the new version of the firmware patch? The unused functions
will not be merged so only request_firmware() and release_firmware()
can be included. If not, I can include my firmware patch that I wrote
before.

=
From: Danilo Krummrich 
Date: Fri, 7 Jun 2024 20:14:59 +0900
Subject: [PATCH] add abstraction for struct device

Add abstraction for struct device. This implements only the minimum
necessary functions required for the abstractions of firmware API;
that is, wrapping C's pointer to a device object with Rust struct only
during a caller knows the pointer is valid (e.g., the probe callback).

Co-developed-by: Wedson Almeida Filho 
Signed-off-by: Wedson Almeida Filho 
Signed-off-by: Danilo Krummrich 
Co-developed-by: FUJITA Tomonori 
Signed-off-by: FUJITA Tomonori 
Acked-by: Greg Kroah-Hartman 
---
 rust/kernel/device.rs | 31 +++
 rust/kernel/lib.rs|  1 +
 2 files changed, 32 insertions(+)
 create mode 100644 rust/kernel/device.rs

diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
new file mode 100644
index ..55ec4f364628
--- /dev/null
+++ b/rust/kernel/device.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Generic devices that are part of the kernel's driver model.
+//!
+//! C header: [`include/linux/device.h`](srctree/include/linux/device.h)
+
+use crate::types::Opaque;
+
+/// Wraps the kernel's `struct task_struct`.
+#[repr(transparent)]
+pub struct Device(Opaque);
+
+impl Device {
+/// Creates a new [`Device`] instance from a raw pointer.
+///
+/// # Safety
+///
+/// For the duration of 'a, the pointer must point at a valid `device`.
+pub unsafe fn from_raw<'a>(ptr: *mut bindings::device) -> &'a Self {
+// CAST: `Self` is a `repr(transparent)` wrapper around 
`bindings::device`.
+let ptr = ptr.cast::();
+// SAFETY: by the function requirements the pointer is valid and we 
have unique access for
+// the duration of `'a`.
+unsafe {  *ptr }
+}
+
+/// Returns the raw pointer to the device.
+pub(crate) fn as_raw() -> *mut bindings::device {
+self.0.get()
+}
+}
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index fbd91a48ff8b..dd1207f1a873 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -28,6 +28,7 @@
 
 pub mod alloc;
 mod build_assert;
+pub mod device;
 pub mod error;
 pub mod init;
 pub mod ioctl;
-- 
2.34.1



Re: [RFC PATCH 7/8] rust: add firmware abstractions

2024-05-31 Thread FUJITA Tomonori
On Thu, 30 May 2024 08:47:25 +0200
Danilo Krummrich  wrote:

>> >> >> For a Rust PHY driver, you know that you have a valid pointer to C's
>> >> >> device object of C's PHY device during the probe callback. The driver
>> >> >> creates a Rust device object to wrap the C pointer to the C's device
>> >> >> object and passes it to the firmware abstractions. The firmware
>> >> >> abstractions gets the C's pointer from the Rust object and calls C's
>> >> >> function to load firmware, returns the result.
>> >> >> 
>> >> >> You have concerns about the simple code like the following?
>> >> >> 
>> >> >> 
>> >> >> diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
>> >> >> new file mode 100644
>> >> >> index ..6144437984a9
>> >> >> --- /dev/null
>> >> >> +++ b/rust/kernel/device.rs
>> >> >> @@ -0,0 +1,30 @@
>> >> >> +// SPDX-License-Identifier: GPL-2.0
>> >> >> +
>> >> >> +//! Generic devices that are part of the kernel's driver model.
>> >> >> +//!
>> >> >> +//! C header: 
>> >> >> [`include/linux/device.h`](srctree/include/linux/device.h)
>> >> >> +
>> >> >> +use crate::types::Opaque;
>> >> >> +
>> >> >> +#[repr(transparent)]
>> >> >> +pub struct Device(Opaque);
>> >> >> +
>> >> >> +impl Device {
>> >> >> +/// Creates a new [`Device`] instance from a raw pointer.
>> >> >> +///
>> >> >> +/// # Safety
>> >> >> +///
>> >> >> +/// For the duration of 'a, the pointer must point at a valid 
>> >> >> `device`.
>> >> > 
>> >> > If the following rust code does what this comment says, then sure, I'm
>> >> > ok with it for now if it helps you all out with stuff like the firmware
>> >> > interface for the phy rust code.
>> >> 
>> >> Great, thanks a lot!
>> >> 
>> >> Danilo and Wedson, are there any concerns about pushing this patch [1]
>> >> for the firmware abstractions?
>> > 
>> > Well, if everyone is fine with this one I don't see why we can't we go 
>> > with [1]
>> > directly? AFAICS, we'd only need the following fix:
>> > 
>> > -//! C header: 
>> > [`include/linux/device.h`](../../../../include/linux/device.h)
>> > +//! C header: [`include/linux/device.h`](srctree/include/linux/device.h)
>> > 
>> > [1] 
>> > https://lore.kernel.org/rust-for-linux/20240520172554.182094-2-d...@redhat.com/
>> 
>> The difference is that your patch touches the reference count of a
>> struct device. My patch doesn't.
>> 
>> The following part in your patch allows the rust code to freely play
>> with the reference count of a struct device. Your Rust drm driver
>> interact with the reference count in a different way than C's drm
>> drivers if I understand correctly. I'm not sure that Greg will be
>> convinenced with that approach.
> 
> I don't see how this is different than what we do in C. If you (for whatever
> reason) want to keep a pointer to a struct device you should make sure to
> increase the reference count of this device, such that it can't get freed for
> the time being.
> 
> This is a 1:1 representation of that and conceptually identical.

A drm driver does such? If a drm driver allocates two types of
driver-specific data and keep a pointer to the pci device, then the
driver calls get_device() twice to increase the reference count of the
pci's device?

At the very least, network device drivers don't. a driver doesn't play
with the reference count. The network subsystem does. And, the network
subsystem doesn't care about how many pointers to a pci device a
driver keeps.

With the patch [1], a driver plays with the reference count of a
device and directly calls get/put_device. It's a different than C
drivers for me (not sure about drm subsystem though).

But I might be misunderstanding that Greg isn't convinced with this
reference count thing. We need to wait for his response.


>> +// SAFETY: Instances of `Device` are always ref-counted.
>> +unsafe impl crate::types::AlwaysRefCounted for Device {
>> +fn inc_ref() {
>> +// SAFETY: The existence of a shared reference guarantees that the 
>> refcount is nonzero.
>> +unsafe { bindings::get_device(self.as_raw()) };
>> +}
>> +
>> +unsafe fn dec_ref(obj: ptr::NonNull) {
>> +// SAFETY: The safety requirements guarantee that the refcount is 
>> nonzero.
>> +unsafe { bindings::put_device(obj.cast().as_ptr()) }
>> +}
>> +}
>> 
>> The following comments give the impression that Rust abstractions
>> wrongly interact with the reference count; callers check out the
>> reference counter. Nobody should do that.
> 
> No, saying that the caller must ensure that the device "has a non-zero 
> reference
> count" is a perfectly valid requirement.
> 
> It doensn't mean that the calling code has to peek the actual reference count,
> but it means that it must be ensured that while we try to increase the 
> reference
> count it can't drop to zero unexpectedly.

Yeah, the same requirements but expressed differently.

But again, I might be misunderstanding. Greg might have a different reason.

> Your patch, as a subset of 

Re: [RFC PATCH 7/8] rust: add firmware abstractions

2024-05-29 Thread FUJITA Tomonori
Hi,

On Thu, 30 May 2024 04:01:39 +0200
Danilo Krummrich  wrote:

> On Thu, May 30, 2024 at 08:28:24AM +0900, FUJITA Tomonori wrote:
>> Hi,
>> 
>> On Wed, 29 May 2024 21:57:03 +0200
>> Greg KH  wrote:
>> 
>> >> For a Rust PHY driver, you know that you have a valid pointer to C's
>> >> device object of C's PHY device during the probe callback. The driver
>> >> creates a Rust device object to wrap the C pointer to the C's device
>> >> object and passes it to the firmware abstractions. The firmware
>> >> abstractions gets the C's pointer from the Rust object and calls C's
>> >> function to load firmware, returns the result.
>> >> 
>> >> You have concerns about the simple code like the following?
>> >> 
>> >> 
>> >> diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
>> >> new file mode 100644
>> >> index ..6144437984a9
>> >> --- /dev/null
>> >> +++ b/rust/kernel/device.rs
>> >> @@ -0,0 +1,30 @@
>> >> +// SPDX-License-Identifier: GPL-2.0
>> >> +
>> >> +//! Generic devices that are part of the kernel's driver model.
>> >> +//!
>> >> +//! C header: [`include/linux/device.h`](srctree/include/linux/device.h)
>> >> +
>> >> +use crate::types::Opaque;
>> >> +
>> >> +#[repr(transparent)]
>> >> +pub struct Device(Opaque);
>> >> +
>> >> +impl Device {
>> >> +/// Creates a new [`Device`] instance from a raw pointer.
>> >> +///
>> >> +/// # Safety
>> >> +///
>> >> +/// For the duration of 'a, the pointer must point at a valid 
>> >> `device`.
>> > 
>> > If the following rust code does what this comment says, then sure, I'm
>> > ok with it for now if it helps you all out with stuff like the firmware
>> > interface for the phy rust code.
>> 
>> Great, thanks a lot!
>> 
>> Danilo and Wedson, are there any concerns about pushing this patch [1]
>> for the firmware abstractions?
> 
> Well, if everyone is fine with this one I don't see why we can't we go with 
> [1]
> directly? AFAICS, we'd only need the following fix:
> 
> -//! C header: [`include/linux/device.h`](../../../../include/linux/device.h)
> +//! C header: [`include/linux/device.h`](srctree/include/linux/device.h)
> 
> [1] 
> https://lore.kernel.org/rust-for-linux/20240520172554.182094-2-d...@redhat.com/

The difference is that your patch touches the reference count of a
struct device. My patch doesn't.

The following part in your patch allows the rust code to freely play
with the reference count of a struct device. Your Rust drm driver
interact with the reference count in a different way than C's drm
drivers if I understand correctly. I'm not sure that Greg will be
convinenced with that approach.

+// SAFETY: Instances of `Device` are always ref-counted.
+unsafe impl crate::types::AlwaysRefCounted for Device {
+fn inc_ref() {
+// SAFETY: The existence of a shared reference guarantees that the 
refcount is nonzero.
+unsafe { bindings::get_device(self.as_raw()) };
+}
+
+unsafe fn dec_ref(obj: ptr::NonNull) {
+// SAFETY: The safety requirements guarantee that the refcount is 
nonzero.
+unsafe { bindings::put_device(obj.cast().as_ptr()) }
+}
+}

The following comments give the impression that Rust abstractions
wrongly interact with the reference count; callers check out the
reference counter. Nobody should do that.

+/// Callers must ensure that `ptr` is valid, non-null, and has a non-zero 
reference count.
+pub unsafe fn from_raw(ptr: *mut bindings::device) -> ARef {

+/// Callers must ensure that `ptr` is valid, non-null, and has a non-zero 
reference count for
+/// the entire duration when the returned reference exists.
+pub unsafe fn as_ref<'a>(ptr: *mut bindings::device) -> &'a Self {
+// SAFETY: Guaranteed by the safety requirements of the function.
+unsafe { &*ptr.cast() }
+}


Re: [RFC PATCH 7/8] rust: add firmware abstractions

2024-05-29 Thread FUJITA Tomonori
Hi,

On Wed, 29 May 2024 21:57:03 +0200
Greg KH  wrote:

>> For a Rust PHY driver, you know that you have a valid pointer to C's
>> device object of C's PHY device during the probe callback. The driver
>> creates a Rust device object to wrap the C pointer to the C's device
>> object and passes it to the firmware abstractions. The firmware
>> abstractions gets the C's pointer from the Rust object and calls C's
>> function to load firmware, returns the result.
>> 
>> You have concerns about the simple code like the following?
>> 
>> 
>> diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
>> new file mode 100644
>> index ..6144437984a9
>> --- /dev/null
>> +++ b/rust/kernel/device.rs
>> @@ -0,0 +1,30 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +//! Generic devices that are part of the kernel's driver model.
>> +//!
>> +//! C header: [`include/linux/device.h`](srctree/include/linux/device.h)
>> +
>> +use crate::types::Opaque;
>> +
>> +#[repr(transparent)]
>> +pub struct Device(Opaque);
>> +
>> +impl Device {
>> +/// Creates a new [`Device`] instance from a raw pointer.
>> +///
>> +/// # Safety
>> +///
>> +/// For the duration of 'a, the pointer must point at a valid `device`.
> 
> If the following rust code does what this comment says, then sure, I'm
> ok with it for now if it helps you all out with stuff like the firmware
> interface for the phy rust code.

Great, thanks a lot!

Danilo and Wedson, are there any concerns about pushing this patch [1]
for the firmware abstractions?

I you prefer to be the author of the patch, please let me know. Who
the author is doesn't matter to me. Otherwise, I'll add
Co-developed-by tag.

[1] 
https://lore.kernel.org/rust-for-linux/20240529.092821.1593412345609718860.fujita.tomon...@gmail.com/


Re: [RFC PATCH 7/8] rust: add firmware abstractions

2024-05-28 Thread FUJITA Tomonori
On Tue, 28 May 2024 14:19:24 +0200
Danilo Krummrich  wrote:

> On Tue, May 28, 2024 at 08:01:26PM +0900, FUJITA Tomonori wrote:
>> On Mon, 27 May 2024 21:22:47 +0200
>> Danilo Krummrich  wrote:
>> 
>> >> > +/// Abstraction around a C firmware struct.
>> >> > +///
>> >> > +/// This is a simple abstraction around the C firmware API. Just like 
>> >> > with the C API, firmware can
>> >> > +/// be requested. Once requested the abstraction provides direct 
>> >> > access to the firmware buffer as
>> >> > +/// `&[u8]`. Alternatively, the firmware can be copied to a new buffer 
>> >> > using `Firmware::copy`. The
>> >> > +/// firmware is released once [`Firmware`] is dropped.
>> >> > +///
>> >> > +/// # Examples
>> >> > +///
>> >> > +/// ```
>> >> > +/// let fw = Firmware::request("path/to/firmware.bin", dev.as_ref())?;
>> >> > +/// driver_load_firmware(fw.data());
>> >> > +/// ```
>> >> > +pub struct Firmware(Opaque<*const bindings::firmware>);
>> >> 
>> >> Wrapping a raw pointer is not the intended use of Qpaque type?
>> >> 
>> > 
>> > Indeed, will fix this in v2 and use NonNull instead. I'll also offload 
>> > most of
>> > the boilerplate in the 'request' functions to some common 
>> > 'request_internal' one.
>> 
>> You might need to add 'Invariants' comment on Firmware struct.
> 
> Which ones do you think should be documented?

Something like the comment for struct Page looks fine to me. But the
Rust reviewers might have a different opinion.

/// The pointer is valid, and has ownership over the page.


Re: [RFC PATCH 7/8] rust: add firmware abstractions

2024-05-28 Thread FUJITA Tomonori
Hi,

On Tue, 28 May 2024 14:45:02 +0200
Greg KH  wrote:

> On Tue, May 28, 2024 at 02:19:24PM +0200, Danilo Krummrich wrote:
>> However, if you have a driver that needs the firmware abstractions, I would 
>> be
>> surprised if there were any hesitations to already merge the minimum device
>> abstractions [1] and this one (once reviewed) without the rest. At least 
>> there
>> aren't any from my side.
>> 
>> [1] 
>> https://lore.kernel.org/rust-for-linux/20240520172554.182094-2-d...@redhat.com/
> 
> No, the device abstractions are NOT ready for merging just yet, sorry,
> if for no other reason than a non-RFC has never been posted :)

Indeed, I understand that you aren't convinced.

We can start with much simpler device abstractions than the above
minimum for the firmware abstractions.

All the firmware abstractions need is wrapping C's pointer to a device
object with Rust struct only during a caller knows the pointer is
valid. No play with the reference count of a struct device.

For a Rust PHY driver, you know that you have a valid pointer to C's
device object of C's PHY device during the probe callback. The driver
creates a Rust device object to wrap the C pointer to the C's device
object and passes it to the firmware abstractions. The firmware
abstractions gets the C's pointer from the Rust object and calls C's
function to load firmware, returns the result.

You have concerns about the simple code like the following?


diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
new file mode 100644
index ..6144437984a9
--- /dev/null
+++ b/rust/kernel/device.rs
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Generic devices that are part of the kernel's driver model.
+//!
+//! C header: [`include/linux/device.h`](srctree/include/linux/device.h)
+
+use crate::types::Opaque;
+
+#[repr(transparent)]
+pub struct Device(Opaque);
+
+impl Device {
+/// Creates a new [`Device`] instance from a raw pointer.
+///
+/// # Safety
+///
+/// For the duration of 'a, the pointer must point at a valid `device`.
+pub unsafe fn from_raw<'a>(ptr: *mut bindings::device) -> &'a Self {
+// CAST: `Self` is a `repr(transparent)` wrapper around 
`bindings::device`.
+let ptr = ptr.cast::();
+// SAFETY: by the function requirements the pointer is valid and we 
have unique access for
+// the duration of `'a`.
+unsafe {  *ptr }
+}
+
+/// Returns the raw pointer to the device.
+pub fn as_raw() -> *mut bindings::device {
+self.0.get()
+}
+}


Re: [RFC PATCH 7/8] rust: add firmware abstractions

2024-05-28 Thread FUJITA Tomonori
On Mon, 27 May 2024 21:22:47 +0200
Danilo Krummrich  wrote:

>> > +/// Abstraction around a C firmware struct.
>> > +///
>> > +/// This is a simple abstraction around the C firmware API. Just like 
>> > with the C API, firmware can
>> > +/// be requested. Once requested the abstraction provides direct access 
>> > to the firmware buffer as
>> > +/// `&[u8]`. Alternatively, the firmware can be copied to a new buffer 
>> > using `Firmware::copy`. The
>> > +/// firmware is released once [`Firmware`] is dropped.
>> > +///
>> > +/// # Examples
>> > +///
>> > +/// ```
>> > +/// let fw = Firmware::request("path/to/firmware.bin", dev.as_ref())?;
>> > +/// driver_load_firmware(fw.data());
>> > +/// ```
>> > +pub struct Firmware(Opaque<*const bindings::firmware>);
>> 
>> Wrapping a raw pointer is not the intended use of Qpaque type?
>> 
> 
> Indeed, will fix this in v2 and use NonNull instead. I'll also offload most of
> the boilerplate in the 'request' functions to some common 'request_internal' 
> one.

You might need to add 'Invariants' comment on Firmware struct.

BTW, what merge window are you aiming for? As I wrote before, I have a
driver that needs the firmware abstractions (the minimum device
abstractions is enough; Device::as_raw() and as_ref()). So the sooner,
the better for me.


Re: [RFC PATCH 7/8] rust: add firmware abstractions

2024-05-28 Thread FUJITA Tomonori
Hi,

On Tue, 28 May 2024 08:40:20 +
Zhi Wang  wrote:

> On 27/05/2024 22.18, Danilo Krummrich wrote:
>> External email: Use caution opening links or attachments
>> 
>> 
>> On Tue, May 21, 2024 at 08:32:31AM +0300, Zhi Wang wrote:
>>> On Mon, 20 May 2024 19:24:19 +0200
>>> Danilo Krummrich  wrote:
>>>
 Add an abstraction around the kernels firmware API to request firmware
 images. The abstraction provides functions to access the firmware
 buffer and / or copy it to a new buffer allocated with a given
 allocator backend.

>>>
>>> Was playing with firmware extractions based on this patch.
>>> Unfortunately I ended up with a lot of pointer operations, unsafe
>>> statements.
>>>
>>> As we know many vendors have a C headers for the definitions of the
>>> firwmare content, the driver extract the data by applying a struct
>>> pointer on it.
>>>
>>> But in rust, I feel it would nice that we can also have a common
>>> firmware extractor for drivers, that can wrap the pointer operations,
>>> take a list of the firmware struct members that converted from C headers
>>> as the input, offer the driver some common ABI methods to query them.
>>> Maybe that would ease the pain a lot.
>> 
>> So, you mean some abstraction that takes a list of types, offsets in the
>> firmware and a reference to the firmware itself and provides references to 
>> the
>> corresponding objects?
>> 
>> I agree it might be helpful to have some common infrastructure for this, but 
>> the
>> operations on it would still be unsafe, since ultimately it involves
>> dereferencing pointers.
>> 
> 
> I think the goal is to 1) concentrate the "unsafe" operations in a 
> abstraction so the driver doesn't have to write explanation of unsafe 
> operations here and there, improve the readability of the driver that 
> interacts with vendor-firmware buffer. 2) ease the driver maintenance 
> burden.
> 
> Some solutions I saw in different projects written in rust for 
> de-referencing a per-defined struct:

Aren't there other abstractions that require that functionality, not
just the firmware abstractions?


Re: [RFC PATCH 7/8] rust: add firmware abstractions

2024-05-22 Thread FUJITA Tomonori
Hi,

On Wed, 22 May 2024 09:37:30 +0200
Philipp Stanner  wrote:

>> > +/// Abstraction around a C firmware struct.
>> > +///
>> > +/// This is a simple abstraction around the C firmware API. Just
>> > like with the C API, firmware can
>> > +/// be requested. Once requested the abstraction provides direct
>> > access to the firmware buffer as
>> > +/// `&[u8]`. Alternatively, the firmware can be copied to a new
>> > buffer using `Firmware::copy`. The
>> > +/// firmware is released once [`Firmware`] is dropped.
>> > +///
>> > +/// # Examples
>> > +///
>> > +/// ```
>> > +/// let fw = Firmware::request("path/to/firmware.bin",
>> > dev.as_ref())?;
>> > +/// driver_load_firmware(fw.data());
>> > +/// ```
>> > +pub struct Firmware(Opaque<*const bindings::firmware>);
>> 
>> Wrapping a raw pointer is not the intended use of Qpaque type?
>> 
> 
> What is the intended use?
> As I see it, all uses wrapp some binding::* – but a rawpointer to a
> binding shouldn't be wrapped by it?

If I understand correctly, it's for embedding C's struct in Rust's
struct (as all the usage in the tree do). It gives the tricks for
initialization and a pointer to the embedded object.

The C's firmware API gives a pointer to an initialized object so no
reason to use Opaque.

With such C API, Rust's struct simply uses raw pointers in old rust
branch. For example,

https://github.com/Rust-for-Linux/linux/blob/rust/rust/kernel/chrdev.rs#L28

struct Cdev(*mut bindings::cdev);


Another choice that I know is NonNull:

https://lore.kernel.org/lkml/20240415-alice-mm-v5-4-6f55e4d8e...@google.com/

pub struct Page {
page: NonNull,
}


Re: [RFC PATCH 7/8] rust: add firmware abstractions

2024-05-22 Thread FUJITA Tomonori
Hi,
Thanks for working on the firmware API!

On Mon, 20 May 2024 19:24:19 +0200
Danilo Krummrich  wrote:

> Add an abstraction around the kernels firmware API to request firmware
> images. The abstraction provides functions to access the firmware
> buffer and / or copy it to a new buffer allocated with a given allocator
> backend.
> 
> The firmware is released once the abstraction is dropped.
> 
> Signed-off-by: Danilo Krummrich 
> ---
>  rust/bindings/bindings_helper.h |  1 +
>  rust/kernel/firmware.rs | 74 +
>  rust/kernel/lib.rs  |  1 +
>  3 files changed, 76 insertions(+)
>  create mode 100644 rust/kernel/firmware.rs
> 
> diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
> index b245db8d5a87..e4ffc47da5ec 100644
> --- a/rust/bindings/bindings_helper.h
> +++ b/rust/bindings/bindings_helper.h
> @@ -14,6 +14,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> diff --git a/rust/kernel/firmware.rs b/rust/kernel/firmware.rs
> new file mode 100644
> index ..700504fb3c9c
> --- /dev/null
> +++ b/rust/kernel/firmware.rs
> @@ -0,0 +1,74 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! Firmware abstraction
> +//!
> +//! C header: 
> [`include/linux/firmware.h`](../../../../include/linux/firmware.h")
> +
> +use crate::{bindings, device::Device, error::Error, error::Result, 
> str::CStr, types::Opaque};
> +
> +/// Abstraction around a C firmware struct.
> +///
> +/// This is a simple abstraction around the C firmware API. Just like with 
> the C API, firmware can
> +/// be requested. Once requested the abstraction provides direct access to 
> the firmware buffer as
> +/// `&[u8]`. Alternatively, the firmware can be copied to a new buffer using 
> `Firmware::copy`. The
> +/// firmware is released once [`Firmware`] is dropped.
> +///
> +/// # Examples
> +///
> +/// ```
> +/// let fw = Firmware::request("path/to/firmware.bin", dev.as_ref())?;
> +/// driver_load_firmware(fw.data());
> +/// ```
> +pub struct Firmware(Opaque<*const bindings::firmware>);

Wrapping a raw pointer is not the intended use of Qpaque type?


[PATCH 01/11] swiotlb: Expose swiotlb_nr_tlb function to modules

2011-10-22 Thread FUJITA Tomonori
On Wed, 19 Oct 2011 18:19:22 -0400
Konrad Rzeszutek Wilk  wrote:

> As a mechanism to detect whether SWIOTLB is enabled or not.
> We also fix the spelling - it was swioltb instead of
> swiotlb.
> 
> CC: FUJITA Tomonori 
> [v1: Ripped out swiotlb_enabled]
> Signed-off-by: Konrad Rzeszutek Wilk 
> ---
>  drivers/xen/swiotlb-xen.c |2 +-
>  include/linux/swiotlb.h   |2 +-
>  lib/swiotlb.c |5 +++--
>  3 files changed, 5 insertions(+), 4 deletions(-)

Acked-by: FUJITA Tomonori 


Re: [PATCH 01/11] swiotlb: Expose swiotlb_nr_tlb function to modules

2011-10-22 Thread FUJITA Tomonori
On Wed, 19 Oct 2011 18:19:22 -0400
Konrad Rzeszutek Wilk konrad.w...@oracle.com wrote:

 As a mechanism to detect whether SWIOTLB is enabled or not.
 We also fix the spelling - it was swioltb instead of
 swiotlb.
 
 CC: FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp
 [v1: Ripped out swiotlb_enabled]
 Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com
 ---
  drivers/xen/swiotlb-xen.c |2 +-
  include/linux/swiotlb.h   |2 +-
  lib/swiotlb.c |5 +++--
  3 files changed, 5 insertions(+), 4 deletions(-)

Acked-by: FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 4/9] swiotlb: Expose swiotlb_nr_tlb function to modules

2011-10-01 Thread FUJITA Tomonori
On Thu, 29 Sep 2011 16:33:47 -0400
Konrad Rzeszutek Wilk konrad.w...@oracle.com wrote:

 As a mechanism to detect whether SWIOTLB is enabled or not.
 We also fix the spelling - it was swioltb instead of
 swiotlb.
 
 CC: FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp
 [v1: Ripped out swiotlb_enabled]
 Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com
 ---
  drivers/xen/swiotlb-xen.c |2 +-
  include/linux/swiotlb.h   |2 +-
  lib/swiotlb.c |5 +++--
  3 files changed, 5 insertions(+), 4 deletions(-)

Acked-by: FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 4/9] swiotlb: Expose swiotlb_nr_tlb function to modules

2011-09-30 Thread FUJITA Tomonori
On Thu, 29 Sep 2011 16:33:47 -0400
Konrad Rzeszutek Wilk  wrote:

> As a mechanism to detect whether SWIOTLB is enabled or not.
> We also fix the spelling - it was swioltb instead of
> swiotlb.
> 
> CC: FUJITA Tomonori 
> [v1: Ripped out swiotlb_enabled]
> Signed-off-by: Konrad Rzeszutek Wilk 
> ---
>  drivers/xen/swiotlb-xen.c |2 +-
>  include/linux/swiotlb.h   |2 +-
>  lib/swiotlb.c |5 +++--
>  3 files changed, 5 insertions(+), 4 deletions(-)

Acked-by: FUJITA Tomonori 


Re: [PATCH 4/7] swiotlb: Expose swiotlb_nr_tlb function to modules as swiotlb_enabled

2011-09-19 Thread FUJITA Tomonori
On Tue, 13 Sep 2011 10:12:47 -0400
Konrad Rzeszutek Wilk konrad.w...@oracle.com wrote:

 As a mechanism to detect whether SWIOTLB is enabled or not.
 And as such, we might as well wrap it within an 'swiotlb_enabled()'
 function that will call the swiotlb_nr_tlb.
 
 We also fix the spelling - it was swioltb instead of
 swiotlb.
 
 CC: FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp
 Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com
 ---
  drivers/xen/swiotlb-xen.c |2 +-
  include/linux/swiotlb.h   |7 ++-
  lib/swiotlb.c |5 +++--
  3 files changed, 10 insertions(+), 4 deletions(-)

Can we just use swiotlb_nr_tbl() rather than inventing a new function
that only wraps swiotlb_nr_tbl()?

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 4/7] swiotlb: Expose swiotlb_nr_tlb function to modules as swiotlb_enabled

2011-09-17 Thread FUJITA Tomonori
On Tue, 13 Sep 2011 10:12:47 -0400
Konrad Rzeszutek Wilk  wrote:

> As a mechanism to detect whether SWIOTLB is enabled or not.
> And as such, we might as well wrap it within an 'swiotlb_enabled()'
> function that will call the swiotlb_nr_tlb.
> 
> We also fix the spelling - it was swioltb instead of
> swiotlb.
> 
> CC: FUJITA Tomonori 
> Signed-off-by: Konrad Rzeszutek Wilk 
> ---
>  drivers/xen/swiotlb-xen.c |2 +-
>  include/linux/swiotlb.h   |7 ++-
>  lib/swiotlb.c |5 +++--
>  3 files changed, 10 insertions(+), 4 deletions(-)

Can we just use swiotlb_nr_tbl() rather than inventing a new function
that only wraps swiotlb_nr_tbl()?



Re: Problems with alpha/pci + radeon/ttm

2010-06-28 Thread FUJITA Tomonori
On Thu, 24 Jun 2010 21:51:40 +1200
Michael Cree mc...@orcon.net.nz wrote:

  Is this a regression (what kernel version worked)?
 
  Seems that the IOMMU can't find 128 pages. It's likely due to:
 
  - out of the IOMMU space (possibly someone doesn't free the IOMMU
space).
 
  or
 
  - the mapping parameters (such as align) aren't appropriate so the
IOMMU can't find space.
 
  I don't think KMS drivers have ever worked on alpha so its not a
  regression, they are working fine on x86 + powerpc and sparc has been
  run at least once.
 
 KMS on the console boot up has worked since about 2.6.32, but starting 
 up the X server has always failed and, in my case, the system becomes 
 unstable and eventually OOPs.
 
  I suspect we are simply hitting the limits of the iommu, how big an
  address space does it handle? since generally graphics drivers try to
  bind a lot of things to the GART.
 
 No idea on the address space limit.  I applied the patch of Fujita that 
 logs all IOMMU allocations, and also inserted some extra printks in the 
 ttm kernel code so that I could see which routines failed and the error 
 code returned.  Running the radeon test on boot exhibits the following:
 
 [  238.712768] [drm] Tested GTT-VRAM and VRAM-GTT copy for GTT offset 
 0x1a312000
 [  239.281127] [drm] Tested GTT-VRAM and VRAM-GTT copy for GTT offset 
 0x1a412000
 [  239.281127] ttm_tt_bind belched -12
 [  239.282104] ttm_bo_handle_move_mem belched -12
 [  239.282104] ttm_bo_move_buffer belched -12
 [  239.282104] ttm_bo_validate belched -12
 [  239.282104] radeon :01:00.0: object_init failed for (1048576, 
 0x0002) err=-12
 [  239.282104] [drm:radeon_test_moves] *ERROR* Failed to create GTT 
 object 419
 [  239.399291] Error while testing BO move.
 
 Note that no IOMMU allocations are printed while radeon_test_moves is 
 running so iommu_arena_alloc doesn't appear to be called.  Also the 
 error code returned up to radeon_test_moves is -12 which is ENOMEM.  So 
 does appear to be some memory limit.

Hmm, not related with IOMMU? looks like ttm_tt_populate could return
ENOMEM too. Can we locate where we hit ENOMEM first?
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Problems with alpha/pci + radeon/ttm

2010-06-27 Thread FUJITA Tomonori
On Thu, 24 Jun 2010 21:51:40 +1200
Michael Cree  wrote:

> >> Is this a regression (what kernel version worked)?
> >>
> >> Seems that the IOMMU can't find 128 pages. It's likely due to:
> >>
> >> - out of the IOMMU space (possibly someone doesn't free the IOMMU
> >>   space).
> >>
> >> or
> >>
> >> - the mapping parameters (such as align) aren't appropriate so the
> >>   IOMMU can't find space.
> >
> > I don't think KMS drivers have ever worked on alpha so its not a
> > regression, they are working fine on x86 + powerpc and sparc has been
> > run at least once.
> 
> KMS on the console boot up has worked since about 2.6.32, but starting 
> up the X server has always failed and, in my case, the system becomes 
> unstable and eventually OOPs.
> 
> > I suspect we are simply hitting the limits of the iommu, how big an
> > address space does it handle? since generally graphics drivers try to
> > bind a lot of things to the GART.
> 
> No idea on the address space limit.  I applied the patch of Fujita that 
> logs all IOMMU allocations, and also inserted some extra printks in the 
> ttm kernel code so that I could see which routines failed and the error 
> code returned.  Running the radeon test on boot exhibits the following:
> 
> [  238.712768] [drm] Tested GTT->VRAM and VRAM->GTT copy for GTT offset 
> 0x1a312000
> [  239.281127] [drm] Tested GTT->VRAM and VRAM->GTT copy for GTT offset 
> 0x1a412000
> [  239.281127] ttm_tt_bind belched -12
> [  239.282104] ttm_bo_handle_move_mem belched -12
> [  239.282104] ttm_bo_move_buffer belched -12
> [  239.282104] ttm_bo_validate belched -12
> [  239.282104] radeon :01:00.0: object_init failed for (1048576, 
> 0x0002) err=-12
> [  239.282104] [drm:radeon_test_moves] *ERROR* Failed to create GTT 
> object 419
> [  239.399291] Error while testing BO move.
> 
> Note that no IOMMU allocations are printed while radeon_test_moves is 
> running so iommu_arena_alloc doesn't appear to be called.  Also the 
> error code returned up to radeon_test_moves is -12 which is ENOMEM.  So 
> does appear to be some memory limit.

Hmm, not related with IOMMU? looks like ttm_tt_populate could return
ENOMEM too. Can we locate where we hit ENOMEM first?


Problems with alpha/pci + radeon/ttm

2010-06-27 Thread FUJITA Tomonori
On Thu, 24 Jun 2010 10:53:52 -0400
Matt Turner  wrote:

> > Seems that the IOMMU can't find 128 pages. It's likely due to:
> >
> > - out of the IOMMU space (possibly someone doesn't free the IOMMU
> > ?space).
> >
> > or
> >
> > - the mapping parameters (such as align) aren't appropriate so the
> > ?IOMMU can't find space.
> >
> >
> >> Is this the cause of the bug we're seeing in the report [1]?
> >>
> >> Anyone know what's going wrong here?
> >
> >
> > I've attached a patch to print the debug info about the mapping
> > parameters.
> >
> >
> > diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
> > index d1dbd9a..17cf0d8 100644
> > --- a/arch/alpha/kernel/pci_iommu.c
> > +++ b/arch/alpha/kernel/pci_iommu.c
> > @@ -187,6 +187,10 @@ iommu_arena_alloc(struct device *dev, struct 
> > pci_iommu_arena *arena, long n,
> > ? ? ? ?/* Search for N empty ptes */
> > ? ? ? ?ptes = arena->ptes;
> > ? ? ? ?mask = max(align, arena->align_entry) - 1;
> > +
> > + ? ? ? printk("%s: %p, %p, %d, %ld, %lx, %u\n", __func__, dev, arena, 
> > arena->size,
> > + ? ? ? ? ? ? ?n, mask, align);
> > +
> > ? ? ? ?p = iommu_arena_find_pages(dev, arena, n, mask);
> > ? ? ? ?if (p < 0) {
> > ? ? ? ? ? ? ? ?spin_unlock_irqrestore(>lock, flags);
> 
> Using this patch, I log the attached output.

Your system has 1GB iommu address space. I guess that it's enough for
KSM?

The parameters in the log looks good. But you got this log before you
started X?


Problems with alpha/pci + radeon/ttm

2010-06-22 Thread FUJITA Tomonori
On Mon, 21 Jun 2010 17:19:43 -0400
Matt Turner  wrote:

> Michael Cree and I have been debugging FDO bug 26403 [1]. I tried
> booting with `radeon.test=1` and found this, which I think is related:
> 
> > [drm] Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x202000
> > [drm] Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x302000
> [snip]
> > [drm] Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0xfd02000
> > [drm] Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0xfe02000
> > pci_map_single failed: could not allocate dma page tables
> > [drm:radeon_ttm_backend_bind] *ERROR* failed to bind 128 pages at 0x0FF02000
> > [TTM] Couldn't bind backend.
> > radeon :00:07.0: object_init failed for (1048576, 0x0002)
> > [drm:radeon_test_moves] *ERROR* Failed to create GTT object 253
> > Error while testing BO move.
> 
> From what I can see, the call chain is
> radeon_test_moves
>  (radeon_ttm_backend_bind called through callback function)
>  - radeon_ttm.c:radeon_ttm_backend_bind calls radeon_gart_bind
>   - radeon_gart.c:radeon_gart_bind calls pci_map_page
>- pci_map_page is alpha_pci_map_page, which calls...
> - alpha_pci_map_page calls pci_iommu.c:pci_map_single_1
>  - pci_map_single_1 calls iommu_arena_alloc
>   - iommu_arena_alloc calls iommu_arena_find_pages
>- iommu_arena_find_pages returns non-0
>   - iommu_arena_alloc returns non-0
>  - pci_map_single_1 returns 0 after printing
>"could not allocate dma page tables" error
> - alpha_pci_map_page returns 0 from pci_map_single_1
>   - radeon_gart_bind returns non-0, error path prints
> "*ERROR* failed to bind 128 pages at 0x0FF02000"

This happens in the latest git, right?

Is this a regression (what kernel version worked)?


Seems that the IOMMU can't find 128 pages. It's likely due to:

- out of the IOMMU space (possibly someone doesn't free the IOMMU
  space).

or

- the mapping parameters (such as align) aren't appropriate so the
  IOMMU can't find space.


> Is this the cause of the bug we're seeing in the report [1]?
>
> Anyone know what's going wrong here?


I've attached a patch to print the debug info about the mapping
parameters.


diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index d1dbd9a..17cf0d8 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -187,6 +187,10 @@ iommu_arena_alloc(struct device *dev, struct 
pci_iommu_arena *arena, long n,
/* Search for N empty ptes */
ptes = arena->ptes;
mask = max(align, arena->align_entry) - 1;
+
+   printk("%s: %p, %p, %d, %ld, %lx, %u\n", __func__, dev, arena, 
arena->size,
+  n, mask, align);
+
p = iommu_arena_find_pages(dev, arena, n, mask);
if (p < 0) {
spin_unlock_irqrestore(>lock, flags);



Re: Problems with alpha/pci + radeon/ttm

2010-06-22 Thread FUJITA Tomonori
On Mon, 21 Jun 2010 17:19:43 -0400
Matt Turner matts...@gmail.com wrote:

 Michael Cree and I have been debugging FDO bug 26403 [1]. I tried
 booting with `radeon.test=1` and found this, which I think is related:
 
  [drm] Tested GTT-VRAM and VRAM-GTT copy for GTT offset 0x202000
  [drm] Tested GTT-VRAM and VRAM-GTT copy for GTT offset 0x302000
 [snip]
  [drm] Tested GTT-VRAM and VRAM-GTT copy for GTT offset 0xfd02000
  [drm] Tested GTT-VRAM and VRAM-GTT copy for GTT offset 0xfe02000
  pci_map_single failed: could not allocate dma page tables
  [drm:radeon_ttm_backend_bind] *ERROR* failed to bind 128 pages at 0x0FF02000
  [TTM] Couldn't bind backend.
  radeon :00:07.0: object_init failed for (1048576, 0x0002)
  [drm:radeon_test_moves] *ERROR* Failed to create GTT object 253
  Error while testing BO move.
 
 From what I can see, the call chain is
 radeon_test_moves
  (radeon_ttm_backend_bind called through callback function)
  - radeon_ttm.c:radeon_ttm_backend_bind calls radeon_gart_bind
   - radeon_gart.c:radeon_gart_bind calls pci_map_page
- pci_map_page is alpha_pci_map_page, which calls...
 - alpha_pci_map_page calls pci_iommu.c:pci_map_single_1
  - pci_map_single_1 calls iommu_arena_alloc
   - iommu_arena_alloc calls iommu_arena_find_pages
- iommu_arena_find_pages returns non-0
   - iommu_arena_alloc returns non-0
  - pci_map_single_1 returns 0 after printing
could not allocate dma page tables error
 - alpha_pci_map_page returns 0 from pci_map_single_1
   - radeon_gart_bind returns non-0, error path prints
 *ERROR* failed to bind 128 pages at 0x0FF02000

This happens in the latest git, right?

Is this a regression (what kernel version worked)?


Seems that the IOMMU can't find 128 pages. It's likely due to:

- out of the IOMMU space (possibly someone doesn't free the IOMMU
  space).

or

- the mapping parameters (such as align) aren't appropriate so the
  IOMMU can't find space.


 Is this the cause of the bug we're seeing in the report [1]?

 Anyone know what's going wrong here?


I've attached a patch to print the debug info about the mapping
parameters.


diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index d1dbd9a..17cf0d8 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -187,6 +187,10 @@ iommu_arena_alloc(struct device *dev, struct 
pci_iommu_arena *arena, long n,
/* Search for N empty ptes */
ptes = arena-ptes;
mask = max(align, arena-align_entry) - 1;
+
+   printk(%s: %p, %p, %d, %ld, %lx, %u\n, __func__, dev, arena, 
arena-size,
+  n, mask, align);
+
p = iommu_arena_find_pages(dev, arena, n, mask);
if (p  0) {
spin_unlock_irqrestore(arena-lock, flags);

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel