Skip to content

Conversation

@AlexandruCihodaru
Copy link
Collaborator

  • Added IdAllocator design and documentation
  • Added IdAllocator initial implementation and unit tests

The documentation and implementation of AddressAllocator with IntervalTree backend will be added in a subsequent PR.

Copy link
Collaborator

@studychao studychao left a comment

Choose a reason for hiding this comment

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

Hi, I have added some code review. Please take a look :)

Copy link
Collaborator

@studychao studychao left a comment

Choose a reason for hiding this comment

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

I've added some few more comments, please take a look at them:)

studychao
studychao previously approved these changes Jan 13, 2022
Copy link
Member

@andreeaflorescu andreeaflorescu left a comment

Choose a reason for hiding this comment

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

Thanks for splitting this effort in smaller PRs that are easy to review! 🎊

I did an initial round of review, and I have some question. I still have to look at the tests, and the allocate_id function can be optimized a bit I believe. That's nothing that can't be changed later though.

/// # Example
///
/// ```rust
/// # use vm_allocator::IdAllocator;
Copy link
Member

Choose a reason for hiding this comment

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

We are shifting to writing examples without using unwrap when that is possible, you can take a look at an example here: https://github.com/rust-vmm/vm-fdt/blob/9cfa0c8d7c3032f79589c7b01c8722a37f4cf44f/src/writer.rs#L289

The example should also be a bit more close to how you'd use it in a real life scenario. I'd say that there's value in just adjusting this kind of things before publishing on crates.io, instead of blocking the PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done! ptal.

# vm-allocator

## Design
`vm-allocator` is a crate designed to to provide allocation and release strategies
Copy link
Member

Choose a reason for hiding this comment

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

I think one relevant thing that is missing from this document is the design choice of having one allocator per resource. We should somehow write about this as well.

/// Creates a new instance of IdAllocator that will be used to manage the
/// allocation and release of ids from the interval specified by
/// `range_base` and `range_max`
pub fn new(range_base: u32, range_max: u32) -> Self {
Copy link
Member

Choose a reason for hiding this comment

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

I find u64 to be more future proof because then we could easily re-use the code for addresses as well. We can leave it as is for now though.

Cargo.toml Outdated
authors = [TODO]
authors = ["rust-vmm AWS maintainers <[email protected]>"]
description = "Allocation of resources needed by VMM"
keywords = ["Id", "Address space", "IRQ", "MSI", "MSI-x"]
Copy link
Member

Choose a reason for hiding this comment

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

You can't use space in keywords, it will fail when you'll try to publish it. I also think the keywords are not speaking so much about what the crate does.

I am thinking about a keyword that speaks more about the main action of the crate "allocating resources" than about what is the type of resources that you can allocate. At this point, I can't come up with anything.

Copy link

Choose a reason for hiding this comment

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

This comment about spaces in keywords has not been addressed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have removed keywords to not block this PR in this. We will add it when we find something to put there.

// All ids from the range specified are exhausted.
Overflow,
// An id that is not part of the specified range was requested to be released.
InvalidInput(u32),
Copy link
Member

Choose a reason for hiding this comment

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

If this is only used for out of range IDs, can we rename this to OutOfRange or similar so that the error variant is more verbose?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It is not used only for out of range IDs. This is also returned when we try to release an ID that was never allocated or already released.

Copy link
Member

Choose a reason for hiding this comment

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

Can we have another error for that one instead? InvalidInput is a bit too generic because most of errors are caused by an invalid input in the end.

/// ```
/// Id allocator representation.
pub struct IdAllocator {
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a few comments about the internal design choices of this structure? What I am finding difficult to understand is why do we need to use an interval tree as oppose to just a vector in which we keep the freed ids. I would assume that some trade-offs were made and that these advantages and disadvantages were put in balance, but this kind of information tends to be forgotten, so it's better to keep it next to the code. What I don't particularly like about BTree is Rust is that it's making you implement useful operations that are not yet stabilized (the one that would be useful for us is pop_first).

Also, the allocation strategy should be mentioned somewhere IMHO (i.e. we first try to reserve IDs from previously freed ones), but I am not sure what is the best way to deliver the message.


```rust
/// Id allocator representation.
pub struct IdAllocator {
Copy link

@gsserge gsserge Jan 13, 2022

Choose a reason for hiding this comment

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

If we duplicate part of the implementation in README, then we need to make sure to keep them in sync if something changes (method signatures, doc comments, etc). For example, the current code snippet is already inconsistent: range_end vs range_max in the constructor.

Copy link
Member

Choose a reason for hiding this comment

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

We can also just move the examples either in the code, or in an examples directory. A layout example is available here: https://doc.rust-lang.org/cargo/guide/project-layout.html

/// println!("Interrupt number allocation failed: {:?}", irq_nr);
/// }
/// let irq = 8;
/// let freed_id_result = legacy_irq_allocator.free_id(irq);
Copy link
Member

@jiangliu jiangliu Jan 14, 2022

Choose a reason for hiding this comment

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

What happens if an unallocated id is freed?
We can't guarantee that the allocated irq is 8 here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If an ID that was not allocated before we will return an error. In this line we check to see if the id requested is in the range we are working with. We explicitly check that the ID was allocated self.next_id < id if no we return InvalidInput for now but I think the error name will change.

@jiangliu
Copy link
Member

It would be great to mention the origin of the design/algorithm, either from Cloud Hypervisor or crosvm:)

@AlexandruCihodaru
Copy link
Collaborator Author

@georgepisaltu @andreeaflorescu @gsserge @studychao @jiangliu thank you for your reviews, I have addressed your comments, please take another look.

@gsserge
Copy link

gsserge commented Jan 17, 2022

Two small comments regarding the keywords and the Error impl, otherwise looks good to me.

gsserge
gsserge previously approved these changes Jan 17, 2022
georgepisaltu
georgepisaltu previously approved these changes Jan 17, 2022
Copy link

@georgepisaltu georgepisaltu left a comment

Choose a reason for hiding this comment

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

LGTM!

Added IdAllocator initial implementation and tests.

Signed-off-by: AlexandruCihodaru <[email protected]>
Signed-off-by: AlexandruCihodaru <[email protected]>
Signed-off-by: AlexandruCihodaru <[email protected]>
Signed-off-by: AlexandruCihodaru <[email protected]>
@studychao
Copy link
Collaborator

LGTM:)

@jiangliu jiangliu merged commit 18fc5f6 into rust-vmm:main Jan 21, 2022
@dwmw2
Copy link

dwmw2 commented Feb 25, 2022

It would be great to mention the origin of the design/algorithm, either from Cloud Hypervisor or crosvm:)

"great"?

I think that such a mention is mandatory, for submissions which are derived from other work.

Obviously, for basic licensing reasons, if we re-use any other work we need to know what we're using and where it comes from, and be sure that the licence is compatible. When an engineer adds their Signed-off-by: to a commit, that is what they are promising.

So it's already absolutely required that they know the origin and didn't just paste random stuff they found on Stack Overflow, or the whole project is in jeopardy. Given that, it costs nothing — and demonstrates that they have done their necessary due diligence — to expect them to state it. And is basic courtesy.

If this isn't already documented as a fundamental requirement for the project, it should be.

(Although it should also go without saying, as it's just basic engineer discipline.)

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.

7 participants