From: Paolo Bonzini <pbonzini@redhat.com>
To: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Cc: qemu-devel@nongnu.org,
"Manos Pitsidianakis" <manos.pitsidianakis@linaro.org>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Daniel P . Berrangé" <berrange@redhat.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Hanna Czenczek" <hreitz@redhat.com>,
"Stefan Hajnoczi" <stefanha@redhat.com>
Subject: Re: [PATCH 00/14] rust: example of bindings code for Rust in QEMU
Date: Fri, 5 Jul 2024 10:06:47 +0200 [thread overview]
Message-ID: <CABgObfZVWt4GkH_qAbWqoF7=xXP_mPopRqUbRFxii8Tki5YuBw@mail.gmail.com> (raw)
In-Reply-To: <0d85e013-1c38-4781-8fd6-5e837327f33f@linaro.org>
On Thu, Jul 4, 2024 at 9:26 PM Pierrick Bouvier
<pierrick.bouvier@linaro.org> wrote:
> > Patches 9-10 deal with how to define new subclasses in Rust. They are
> > a lot less polished and less ready. There is probably a lot of polish
> > that could be applied to make the code look nicer, but I guess there is
> > always time to make the code look nicer until the details are sorted out.
> >
> > The things that I considered here are:
> >
> > - splitting configuration from runtime state
> > - automatic generation of instance_init and instance_finalize
> > - generation of C vtables from safe code that is written in Rust
> > - generation of qdev property tables
>
> Shouldn't we focus more on how we want to write a QOM device in Rust
> instead, by making abstraction of existing C implementation first?
> Once we have satisfying idea, we could evaluate how it maps to existing
> implementation, and which compromise should be made for efficiency.
> It seems that the current approach is to stick to existing model, and
> derive Rust bindings from this.
I think I tried to do a little bit of that. For example, the split of
configuration from runtime state is done to isolate the interior
mutability, and the automatic generation of instance_init and
instance_finalize relies on Rust traits like Default and Drop; the
realize implementation returns a qemu::Result<()>; and so on.
But there are many steps towards converting the PL011 device to Rust:
- declarative definitions of bitfields and registers (done)
- using RefCell for mutable state
- using wrappers for class and property definition
- defining and using wrappers for Chardev/CharBackend
- defining and using wrappers for MemoryRegion callbacks
- defining and using wrappers for SysBusDevice functionality
- defining and using wrappers for VMState functionality
At each step we need to design "how we want to do that in Rust" and
all the things you mention above. This prototype covers the second and
third steps, and it's already big enough! :)
I expect that code like this one would be merged together with the
corresponding changes to PL011: the glue code is added to the qemu/
crate and used in the hw/core/pl011/ directory. This way, both authors
and reviewers will have a clue of what becomes more readable/idiomatic
in the resulting code.
> I agree this glue can be a source of technical debt, but on the other
> side, it should be easy to refactor it, if we decided first what the
> "clean and idiomatic" Rust API should look like.
That's true, especially if we want to add more macro magic on top. We
can decide later where to draw the line between complexity of glue
code and cleanliness of Rust code, and also move the line as we see
fit.
On the other hand, if we believe that _this_ code is already too much,
that's also a data point. Again: I don't think it is, but I want us to
make an informed decision.
> A compromise where you have to manually translate some structs, or copy
> memory to traverse languages borders at some point, could be worth the
> safety and expressiveness.
Yep, Error is an example of this. It's not the common case, so it's
totally fine to convert to and from C Error* (which also includes
copying the inner error string, from a String to malloc-ed char*) to
keep the APIs nicer.
> > We should have an idea of what this glue code looks like, in order to make
> > an informed choice. If we think we're not comfortable with reviewing it,
> > well, we should be ready to say so and stick with C until we are.
>
> While it is important that this glue code is maintainable and looks
> great, I don't think it should be the main reason to accept usage of a
> new language.
Not the main reason, but an important factor in judging if we are
*able* to accept usage of a new language. Maybe it's just a formal
step, but it feels safer to have _some_ code to show and to read, even
if it's just a prototype that barely compiles.
> We could have a specific trait with functions to handle various kind of
> events. And the glue code could be responsible to translate this to
> callbacks for the C side (and calling Rust code accordingly, eventually
> serializing this on a single thread to avoid any race issues).
That's a possibility, yes. Something like (totally random):
impl CharBackend {
pub fn start<T: CharBackendCallbacks>(&mut self, obj: &T) {
qemu_chr_fe_set_handlers(self.0,
Some(obj::can_receive),
Some(obj::receive, obj::event),
Some(obj::be_change), obj as *const _ as
*const c_void,
ptr::null(), true);
}
pub fn stop(&mut self) {
qemu_chr_fe_set_handlers(self.0, None, None,
None, ptr::null(), ptr::null(), true);
}
}
but I left for later because I focused just on the lowest levels code
where you could have "one" design. For example, for memory regions
some devices are going to have more than one, so there could be
reasons to do callbacks in different ways. By the way, all of this
passing of Rust references as opaque pointers needs, at least in
theory, to be annotated for pinning. Do we have to make sure that
pinning is handled correctly, or can we just assume that QOM objects
are pinned? I am not sure I am ready to answer the question...
Paolo
next prev parent reply other threads:[~2024-07-05 8:08 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-01 14:58 [PATCH 00/14] rust: example of bindings code for Rust in QEMU Paolo Bonzini
2024-07-01 14:58 ` [PATCH 01/14] add skeleton Paolo Bonzini
2024-07-01 14:58 ` [PATCH 02/14] set expectations Paolo Bonzini
2024-07-01 14:58 ` [PATCH 03/14] rust: define traits and pointer wrappers to convert from/to C representations Paolo Bonzini
2024-07-03 12:48 ` Marc-André Lureau
2024-07-03 12:58 ` Marc-André Lureau
2024-07-03 15:55 ` Paolo Bonzini
2024-09-27 16:09 ` Kevin Wolf
2024-09-27 20:19 ` Paolo Bonzini
2024-09-27 19:36 ` Stefan Hajnoczi
2024-09-27 20:26 ` Paolo Bonzini
2025-05-26 12:35 ` Paolo Bonzini
2024-07-01 14:58 ` [PATCH 04/14] rust: add tests for util::foreign Paolo Bonzini
2024-07-01 14:58 ` [PATCH 05/14] rust: define wrappers for Error Paolo Bonzini
2024-07-01 14:58 ` [PATCH 06/14] rust: define wrappers for basic QOM concepts Paolo Bonzini
2024-07-01 14:58 ` [PATCH 07/14] rust: define wrappers for methods of the QOM Object class Paolo Bonzini
2024-07-01 14:58 ` [PATCH 08/14] rust: define wrappers for methods of the QOM Device class Paolo Bonzini
2024-07-01 14:58 ` [PATCH 09/14] rust: add idiomatic bindings to define Object subclasses Paolo Bonzini
2024-07-01 14:58 ` [PATCH 10/14] rust: add idiomatic bindings to define Device subclasses Paolo Bonzini
2024-07-01 14:58 ` [PATCH 11/14] rust: replace std::ffi::c_char with libc::c_char Paolo Bonzini
2024-07-01 14:58 ` [PATCH 12/14] rust: replace c"" literals with cstr crate Paolo Bonzini
2024-07-01 14:58 ` [PATCH 13/14] rust: introduce alternative to offset_of! Paolo Bonzini
2024-07-01 14:58 ` [PATCH 14/14] rust: use version of toml_edit that does not require new Rust Paolo Bonzini
2024-07-04 19:26 ` [PATCH 00/14] rust: example of bindings code for Rust in QEMU Pierrick Bouvier
2024-07-05 8:06 ` Paolo Bonzini [this message]
2024-07-05 18:52 ` Pierrick Bouvier
2024-07-05 21:08 ` Paolo Bonzini
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='CABgObfZVWt4GkH_qAbWqoF7=xXP_mPopRqUbRFxii8Tki5YuBw@mail.gmail.com' \
--to=pbonzini@redhat.com \
--cc=alex.bennee@linaro.org \
--cc=berrange@redhat.com \
--cc=hreitz@redhat.com \
--cc=manos.pitsidianakis@linaro.org \
--cc=marcandre.lureau@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=pierrick.bouvier@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).