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

Add IO manager support #12

Merged
merged 6 commits into from
Jan 22, 2020
Merged

Add IO manager support #12

merged 6 commits into from
Jan 22, 2020

Conversation

liujing2
Copy link

@liujing2 liujing2 commented Oct 31, 2019

Let's firstly add IO manager which focuses on device Port IO and MMIO management, and static IO mapping in runtime as the first step.
@sameo @andreeaflorescu @jiangliu PTAL, thanks.

@sameo
Copy link

sameo commented Nov 1, 2019

I'm marking that one as WIP for now.

@sameo sameo changed the title Add device manager support [WIP] Add device manager support Nov 1, 2019
@liujing2 liujing2 force-pushed the devmgr-v1 branch 3 times, most recently from 8e9874b to e0424b5 Compare November 5, 2019 11:27
@liujing2 liujing2 changed the title [WIP] Add device manager support [WIP] Add IO manager support Nov 22, 2019
@liujing2 liujing2 changed the title [WIP] Add IO manager support Add IO manager support Nov 22, 2019
@liujing2 liujing2 changed the title Add IO manager support [WIP] Add IO manager support Nov 22, 2019
@liujing2 liujing2 changed the title [WIP] Add IO manager support Add IO manager support Nov 22, 2019
@liujing2
Copy link
Author

liujing2 commented Dec 5, 2019

Could @sameo @andreeaflorescu @jiangliu take a look if there are any more comments? Thanks.

sboeuf
sboeuf previously approved these changes Dec 12, 2019
Copy link

@sboeuf sboeuf left a comment

Choose a reason for hiding this comment

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

Just a few nits, but the PR looks good to me.

@sboeuf
Copy link

sboeuf commented Dec 12, 2019

@liujing2 you need to fix the CI by replacing nth_back() function with something that is not considered unstable.

@liujing2
Copy link
Author

liujing2 commented Dec 13, 2019

@liujing2 you need to fix the CI by replacing nth_back() function with something that is not considered unstable.

Thanks very much for the review.
I noticed the rust issue number directed by our CI result, saying that nth_back() is stabilized in 1.37.0, see
rust-lang/rust#56995 (comment)
That's why I locally have no error. Do we need to update here? @sameo @andreeaflorescu @jiangliu
Otherwise, we need use some other complex handling here.

@sboeuf
Copy link

sboeuf commented Dec 13, 2019

@liujing2 ah ok then I agree we should bump the CI to the latest Rust version.

@sameo
Copy link

sameo commented Dec 17, 2019

@liujing2 Could you please force push to check if CI passes with the new container?

@jiangliu jiangliu requested review from jiangliu and sameo December 30, 2019 11:43
jiangliu
jiangliu previously approved these changes Dec 30, 2019
Copy link

@sameo sameo left a comment

Choose a reason for hiding this comment

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

Overall, the PR looks good.
I would appreciate if we could separate the IO ops internal mutability changes into a separate commit, and also remove the vm-memory dependency (and split the addr argument into base, offset) from vm-device prior to merging that PR.

@liujing2
Copy link
Author

liujing2 commented Jan 9, 2020

Overall, the PR looks good.
I would appreciate if we could separate the IO ops internal mutability changes into a separate commit, and also remove the vm-memory dependency (and split the addr argument into base, offset) from vm-device prior to merging that PR.

Sure, we can separate the PR into three.

  1. remove vm-memory dependency; find a way for the DeviceIO read/write parameters.
  2. Io ops internal mutability changing.
  3. IoManager related.

For the 1st, the difference between passing base offset and passing addr will be only for non-pci device instance, I think. These device instance can use offset directly to handle r/w emulation. But for those pci device instances, especially with several windows, they still need calculate addr(base+offset) and compare with each BAR Base Address to find the right one, right?

@jiangliu
Copy link
Member

jiangliu commented Jan 9, 2020

Overall, the PR looks good.
I would appreciate if we could separate the IO ops internal mutability changes into a separate commit, and also remove the vm-memory dependency (and split the addr argument into base, offset) from vm-device prior to merging that PR.

Sure, we can separate the PR into three.

  1. remove vm-memory dependency; find a way for the DeviceIO read/write parameters.
  2. Io ops internal mutability changing.
  3. IoManager related.

For the 1st, the difference between passing base offset and passing addr will be only for non-pci device instance, I think. These device instance can use offset directly to handle r/w emulation. But for those pci device instances, especially with several windows, they still need calculate addr(base+offset) and compare with each BAR Base Address to find the right one, right?

If 'base + offset' is used, the driver may need to lookup some internal data structures by using base as the key. And token actually caches information about the internal data structures thus avoid the looking up operations.

@sameo
Copy link

sameo commented Jan 10, 2020

If 'base + offset' is used, the driver may need to lookup some internal data structures by using base as the key. And token actually caches information about the internal data structures thus avoid the looking up operations.

Yes, that's right that the device may do some lookup, but this could easily be a O(1) lookup for those devices that actually need to look it up (PCI devices, yes). This seems to me like a micro optimization at that point, and the cost for it is a bound between the IO trait and the IO manager. In other words, callers of the IO trait methods must be stateful by keeping track of a cookie/token. Using this kind of API builds an implicit dependency between the trait and a registration method. To me, that's not the cleanest design, and the benefit we'd get for it is arguable (an O(1) lookup).

@jiangliu
Copy link
Member

jiangliu commented Jan 13, 2020

If 'base + offset' is used, the driver may need to lookup some internal data structures by using base as the key. And token actually caches information about the internal data structures thus avoid the looking up operations.

Yes, that's right that the device may do some lookup, but this could easily be a O(1) lookup for those devices that actually need to look it up (PCI devices, yes). This seems to me like a micro optimization at that point, and the cost for it is a bound between the IO trait and the IO manager. In other words, callers of the IO trait methods must be stateful by keeping track of a cookie/token. Using this kind of API builds an implicit dependency between the trait and a registration method. To me, that's not the cleanest design, and the benefit we'd get for it is arguable (an O(1) lookup).

Ok, let's use (base, offset) tuple, otherwise we are just blocking by small technical points:)
The vm-device is the foundation of the device model, and we have stocked here for a long time.

sboeuf
sboeuf previously approved these changes Jan 13, 2020
/// Device IO trait.
/// A device supporting memory based I/O should implement this trait, then
/// register itself against the different IO type ranges it handles.
/// The VMM will then dispatch IO (PIO or MMIO) VM exits by calling into the
/// registered devices read or write method from this trait.
/// The DeviceIo trait adopts the interior mutability pattern
Copy link
Collaborator

Choose a reason for hiding this comment

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

Having interior mutability here is a thorny issue and needs a separate discussion :( Why do you favor this over the previous interface?

Copy link
Member

Choose a reason for hiding this comment

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

Some users of firecracker have mentioned that lacking support of multi-queue causes performance penalty, so we hope we could enable mutli-queue for virtio devices.
Moving lock into the device backend driver is the first step:)

Copy link

Choose a reason for hiding this comment

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

Having interior mutability here is a thorny issue and needs a separate discussion :( Why do you favor this over the previous interface?

@alexandruag Any further comments on this? I'm ok with this PR, but I'd like to get your opinion on it and see if you want to block it until we agree on the inner mutability part.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hi, apologies for the delay. The problem with assuming interior mutability is many devices mutate their state during normal operation, but have to go out of their way to actually implement interior mutability. I don't know what the best approach is long term (hopefully it'll become clearer as we start putting things together), but one potential solution right now is to add another trait (something like DeviceIoMut) that defines the same methods as DeviceIo but requiring &mut self instead of &self, and then also add a blanket implementation such as impl<T> DeviceIo for Mutex<T> where T: DeviceIoMut { ... }, that allows a Mutex<T> to be used as a DeviceIo object automatically as long as the inner type implements DeviceIoMut (same goes for other standard wrappers that offer interior mutability like RefCell). Does that make any sense?

Copy link
Member

Choose a reason for hiding this comment

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

Great idea, this satisfies both side with an zero overhead abstraction.
How about merging the PR first and sending another PR for the DeviceIoMut proposal?

@jiangliu jiangliu requested review from alexandruag and sameo January 13, 2020 09:49
Copy link

@sameo sameo left a comment

Choose a reason for hiding this comment

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

Once rebased on top of master, this PR will look good to me

Jing Liu added 6 commits January 20, 2020 18:13
Signed-off-by: Jing Liu <[email protected]>
In order to get a real multiple threads handling to enhance
performance, the DeviceIo trait need adopt interior mutability
pattern.

Signed-off-by: Jing Liu <[email protected]>
Based on resources definition, this adds device IO manager to manage
all devices IO ranges.

Signed-off-by: Jing Liu <[email protected]>
IO manager is responsible for handling IO operation when VMExit.
It works out the specific device according to the address range and
hand over to DeviceIo trait.

Signed-off-by: Jing Liu <[email protected]>
Unit tests for IO manager.

Signed-off-by: Jing Liu <[email protected]>
Append missing tests for resources and fix some typo.

Signed-off-by: Jing Liu <[email protected]>
@jiangliu jiangliu merged commit 3daea68 into rust-vmm:master Jan 22, 2020
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.

6 participants