Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vhost-user-backend: simplify the use of generics #155

Merged
merged 1 commit into from
Oct 2, 2023

Conversation

Ablu
Copy link
Collaborator

@Ablu Ablu commented May 10, 2023

In order to allow zero-cost exchanging of the concrete bitmap and vring
types, a lot of the generic code required using a tuple of
<VringType, BitmapType> for parameterizing the impl's. Once code is
also oblivious of the concrete backend (and a lot of code is), this
tuple turns into a triplet. Juggling these three single letter generic
parameters while making sure that all the type constraints (that are
also changing depending on the abstraction layer) does not feel very
ergonomic.

While one can argue that within this crate, this would be fine since
people probably know the internals, the design choice is leaking out
into every consumer of vhost-user-backend. Instead of just being able
to reference "some backend" one needs to copy a lot of boilerplate code
for also passing the other type parameters (again, while making sure
that all the constraints are met).

Instead, this commit changes things to utilize associated types [1].
This makes the Bitmap and Vring types part of the backend trait and
requires the implementations to spell them out. Code that just wants to
use the backend without needing to know the details can now just use
the trait without needing to specify the Bitmap and Vring types again.
Where needed, restricting Bitmap and Vring further is still possible
(though one no longer needs to copy all the existing restrictions and
can keep the code more maintainable by only listing new ones).

Overall, my main target was to improve the ergonomics of the consumers
of the crate. But I think the change also improves the readability and
maintainability within this crate. Combined, this hopefully justifies
the small code breakage in consumers.

No functional changes intended.
No change in type flexibility intended.

BREAKING CHANGE, consumers of the lib will need to adjust their code
(but it should improve the general readability).

Signed-off-by: Erik Schilling erik.schilling@linaro.org

[1] https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#specifying-placeholder-types-in-trait-definitions-with-associated-types

Summary of the PR

Please summarize here why the changes in this PR are needed.

Requirements

Before submitting your PR, please make sure you addressed the following
requirements:

  • All commits in this PR are signed (with git commit -s), and the commit
    message has max 60 characters for the summary and max 75 characters for each
    description line.
  • All added/changed functionality has a corresponding unit/integration
    test.
  • All added/changed public-facing functionality has entries in the "Upcoming
    Release" section of CHANGELOG.md (if no such section exists, please create one).
  • Any newly added unsafe code is properly documented.

@Ablu
Copy link
Collaborator Author

Ablu commented May 10, 2023

CI seems to have timed out? Probably only needs a retrigger...

@jiangliu
Copy link
Member

Once upon a time, we have struggled with rust generic associated types when developing the vm-memory crate, not sure about the latest progess about support of GAT. One good news is that vhost-user-backend is not as fundamental as vm-memory, so GAT may not be an issue for vhost-user-backend.

@Ablu
Copy link
Collaborator Author

Ablu commented May 10, 2023

@jiangliu hm, do you recall the concrete problems? Maybe it was with older rust versions? The only catch that I can think of is that you cannot use a normal generic type parameter in an associated type (I think that only works with dynamic dispatch). But that is a pretty weird case anyway (why not simply leave the type open then and set it on a higher level)?

jiangliu
jiangliu previously approved these changes May 11, 2023
@stsquad
Copy link
Contributor

stsquad commented May 12, 2023

Do you have any examples of the conversion needed to show how its an improvement?

@Ablu
Copy link
Collaborator Author

Ablu commented May 13, 2023

@stsquad: The changes done to VhostUserHandler are probably a good hint at how things improve for consumers. Essentially, the number of generic arguments is simply reduced which makes them a lot saner to write. Right now, every time you want to pass a backend around, you will have to do so while juggling all these parameters (and copying the constraints all over the place).

I can draft a proposal how I was planning the simplify vhost-user in the next days.

@Ablu
Copy link
Collaborator Author

Ablu commented May 17, 2023

@stsquad here is an example train of thought for vhost-user:

  1. Assume that we want to move the boilerplate around creating the daemon into a separate function (for example, in order to share it with the other daemons, or move it into some shared lib)
  2. The code for that, right now, could look like: rust-vmm/vhost-device@a447db5
  3. Forcing the user to spell out, for example, the full VringT type does not looks particulary helpful
  4. Ablu/vhost-device@ed5cafb now show the changes necessary / possible with the associated type changes of this PR.
  5. Mostly, one does not need to spell out ALL the requirements. One only needs to list what VhostUserDaemon puts on top of the VhostUserBackend. I also feel the associated types a bit easier to reason, given that they a) have more descriptive names, b) are immediately understood as types of the backend. Of course there may still be further room for improvement here, but I argue that the new code requires quite a few brain cycles less to process.

The benefits may be larger if code is generic over a VhostUserBackend, but does not need to fulfill further requirements (unlike what VhostUserDaemon demands here). In those cases the entire where could would probably become superfluous. However, I did not find code that uses things in vhost-device or virtiofsd.

Let me know if anything is unclear :).

@Ablu
Copy link
Collaborator Author

Ablu commented Jun 13, 2023

@Ablu Ablu force-pushed the backend-associated-type branch from d4c20d8 to 8b2d589 Compare July 4, 2023 12:28
@Ablu
Copy link
Collaborator Author

Ablu commented Jul 4, 2023

rebased

@stefano-garzarella
Copy link
Member

@Ablu Sorry to just get here now, but I really like this cleanup!
It's going to be quite a change for our users, but I think it's worth it!

Would you like to rebase?
I hope this is the right release cycle to include this change.

@Ablu
Copy link
Collaborator Author

Ablu commented Sep 28, 2023

rebased

sboeuf
sboeuf previously approved these changes Sep 28, 2023
Copy link
Member

@stefano-garzarella stefano-garzarella left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just some minor comments.

crates/vhost-user-backend/src/lib.rs Show resolved Hide resolved
crates/vhost-user-backend/CHANGELOG.md Outdated Show resolved Hide resolved
@Ablu
Copy link
Collaborator Author

Ablu commented Sep 28, 2023

Changelog

  • added link to CHANGELOG
  • fixed format woes

@stefano-garzarella
Copy link
Member

@Ablu do you plan to work on https://github.com/rust-vmm/vhost-device Draft PR to be merged when we do the next release of this crate?

@Ablu
Copy link
Collaborator Author

Ablu commented Sep 28, 2023

@Ablu do you plan to work on https://github.com/rust-vmm/vhost-device Draft PR to be merged when we do the next release of this crate?

Will prepare one!

@Ablu
Copy link
Collaborator Author

Ablu commented Sep 29, 2023

Will prepare one!

rust-vmm/vhost-device#461

@stefano-garzarella
Copy link
Member

@jiangliu @sboeuf you already approved a previous version, this one has only a few minimal changes, can you take a look again? Thanks ;-)

sboeuf
sboeuf previously approved these changes Oct 2, 2023
In order to allow zero-cost exchanging of the concrete bitmap and vring
types, a lot of the generic code required using a tuple of
`<VringType, BitmapType>` for parameterizing the impl's. Once code is
also oblivious of the concrete backend (and a lot of code is), this
tuple turns into a triplet. Juggling these three single letter generic
parameters while making sure that all the type constraints (that are
also changing depending on the abstraction layer) does not feel very
ergonomic.

While one can argue that within this crate, this would be fine since
people probably know the internals, the design choice is leaking out
into every consumer of vhost-user-backend. Instead of just being able
to reference "some backend" one needs to copy a lot of boilerplate code
for also passing the other type parameters (again, while making sure
that all the constraints are met).

Instead, this commit changes things to utilize associated types [1].
This makes the Bitmap and Vring types part of the backend trait and
requires the implementations to spell them out. Code that just wants to
use the backend without needing to know the details can now just use
the trait without needing to specify the Bitmap and Vring types again.
Where needed, restricting Bitmap and Vring further is still possible
(though one no longer needs to copy all the existing restrictions and
can keep the code more maintainable by only listing new ones).

Overall, my main target was to improve the ergonomics of the consumers
of the crate. But I think the change also improves the readability and
maintainability within this crate. Combined, this hopefully justifies
the small code breakage in consumers.

No functional changes intended.
No change in type flexibility intended.

BREAKING CHANGE, consumers of the lib will need to adjust their code
(but it should improve the general readability).

Signed-off-by: Erik Schilling <erik.schilling@linaro.org>

[1] https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#specifying-placeholder-types-in-trait-definitions-with-associated-types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants