Skip to content

Conversation

@sboeuf
Copy link

@sboeuf sboeuf commented May 22, 2019

In order to support use cases where the memory needs to be backed by
actual files in order to be shared across processes (vhost-user case),
this patch introduces a new function creating the guest memory with
each region backed by a file descriptor provided by the caller.

It also introduces two helpers to retrieve file information related
to a region. Each file is owned by the memory region so that the
caller does not have to deal with ownership. This way, the file gets
to live as long as the memory region is active.

Signed-off-by: Sebastien Boeuf sebastien.boeuf@intel.com

@sboeuf sboeuf requested review from bonzini and jiangliu May 22, 2019 19:30
@sboeuf
Copy link
Author

sboeuf commented May 22, 2019

@jiangliu @bonzini @sameo PTAL

This is an attempt to initialize the guest memory the same way it can be done now, but adding the facility to provide a file and an offset for each region.

@sboeuf sboeuf force-pushed the add_fd_support branch 2 times, most recently from 19560fb to 19733a4 Compare May 22, 2019 20:31
rbradford
rbradford previously approved these changes May 23, 2019
Copy link
Contributor

@rbradford rbradford left a comment

Choose a reason for hiding this comment

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

Minor feedback.

mapping: MmapRegion,
guest_base: GuestAddress,
file: Option<File>,
offset: Option<usize>,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should be MemoryRegionAddress

Copy link
Author

Choose a reason for hiding this comment

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

@jiangliu @bonzini do you have any preference here?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think usize is fine for offset here because it's a characteristic of the mmaped file on the host (its original type being off_t, which fits nicely within an usize).

Copy link
Member

@jiangliu jiangliu May 31, 2019

Choose a reason for hiding this comment

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

Maybe a (file, off_t) pair is more staightforward:)

@sboeuf sboeuf force-pushed the add_fd_support branch 2 times, most recently from 9c88452 to 1932cb6 Compare May 23, 2019 15:29
@sboeuf sboeuf requested a review from andreeaflorescu May 24, 2019 23:25
Copy link
Collaborator

@alexandruag alexandruag left a comment

Choose a reason for hiding this comment

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

Did not have a very good look at the tests, will do another pass later. Just wanted to post some preliminary comments.


/// Return the file descriptor pointing to the memory region. Return None
/// if no file descriptor is associated with the region.
fn fd(&self) -> Option<RawFd>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since fd and fd_offset are either both Some(...) or both None, I think it would be nicer to have a single method that returns an Option<(RawFd, usize)>.

Also, just wondering, what's the use case for having them as part of the GuestMemoryRegion trait? If none of the vm-memory consumers actually needs something like this, I would remove them for now.

Btw, I think RawFd doesn't work for Windows; we'll either have to abstract this (like provide a reference to the actual File or smt), or conditionally compile different versions of the method for different platforms.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, just wondering, what's the use case for having them as part of the GuestMemoryRegion trait? If none of the vm-memory consumers actually needs something like this, I would remove them for now.

Needed for vhost.

Copy link
Author

Choose a reason for hiding this comment

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

Since fd and fd_offset are either both Some(...) or both None, I think it would be nicer to have a single method that returns an Option<(RawFd, usize)>.

Yes I agree, I'll change that.

Also, just wondering, what's the use case for having them as part of the GuestMemoryRegion trait? If none of the vm-memory consumers actually needs something like this, I would remove them for now.

Here is a consumer cloud-hypervisor/cloud-hypervisor#30 ;)

Btw, I think RawFd doesn't work for Windows; we'll either have to abstract this (like provide a reference to the actual File or smt), or conditionally compile different versions of the method for different platforms.

Ah yes, what's the preferred way to do this? @sameo @rbradford @jiangliu

Copy link
Collaborator

Choose a reason for hiding this comment

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

Well, one way of not being biased towards unix stuff in this particular case is to return an Option<&File> instead of Option<RawFd> (assuming you have a File object somewhere, which seems to be the case).

Copy link
Member

Choose a reason for hiding this comment

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

Both Raw and File should be OK, but not AsRawFd because it's not Send ready. We could easily construct a File object from RawFd and File is Send/Sync.

Copy link
Author

Choose a reason for hiding this comment

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

Well we would not have to construct the File if we were actually keeping the File. WDYT?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I mean File is as convenient as RawFd, and it's more friend to Windows:)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hi, I've created a PR here with some changes on top of Sebastien's branch that embody the proposals I've made. I don't know where those conflicts came from :( Still, it would be great if you ppl can have a look.

Copy link
Member

Choose a reason for hiding this comment

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

File is better not really because of Windows, since this is meant for SCM_RIGHTS support, but rather because it allows tracking the lifetime correctly. What about a separate struct FileRange:

struct FileRange {
    file: Arc<File>,
    offset: u64,
    size: usize
};

and having a single method that returns Option<FileRange> here?

pub struct GuestRegionMmap {
mapping: MmapRegion,
guest_base: GuestAddress,
file: Option<File>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it's a bit more natural to have file and offset as members of MmapRegion, since they are basically parameters of the mmaped host memory region, and don't have anything to do with the guest. Also, it might be nicer to have a single Option<(File, usize)> instead of two separate Options.

Copy link
Contributor

Choose a reason for hiding this comment

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

@sboeuf Can you investigate MmapRegion instead? It sounds logical. I think if you move it it would also be possible to switch to the @alexandruag's proposed single Option<File, usize>

Copy link
Author

Choose a reason for hiding this comment

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

I think this is feasible, but do you expect me to implement this both for mmap_unix.rs and mmap_windows.rs?

I don't really like to merge the file and the file offset into a tuple, because it's less readable from a code perspective IMO.

Copy link
Collaborator

@alexandruag alexandruag May 28, 2019

Choose a reason for hiding this comment

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

Just for mmap_unix.rs, since in its current state this source file is Unix-specific anyway :P We can reach out to the Windows folks regarding also updating the mmap_windows.rs file.

Btw, if we get vote on readability I like the tuple more, otherwise u end up with gratuitous unwraps just to get a value which you know is present :D

Copy link
Author

Choose a reason for hiding this comment

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

Ah yes you got a point with the unwrap here!

Copy link
Author

Choose a reason for hiding this comment

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

I remember one of the reason I didn't create File as part of the MmapRegion. I wanted the region to own the File. And to do so, I had to invoke try_clone(), which should not be done at the same level the mmap() is done IMO.
Both unix and windows should share the same ownership behavior regarding the File I think.

Copy link
Author

Choose a reason for hiding this comment

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

@jiangliu what do you think about this?

Copy link
Member

Choose a reason for hiding this comment

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

It's feasible to move (file, offset) pair into MmapRegion. I'm also thinking of adding an method to the GuestMemoryRegion trait to expose the (file, offset) info. Then clients like vhost may depend on GuestMemoryRegion instead of GuestRegionMmap.

mapping: MmapRegion,
guest_base: GuestAddress,
file: Option<File>,
offset: Option<usize>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think usize is fine for offset here because it's a characteristic of the mmaped file on the host (its original type being off_t, which fits nicely within an usize).

/// Creates a container and allocates shared memory backed by a file for
/// guest memory regions. Valid memory regions are specified as a Vec of
/// (Address, Size, File, Offset) tuples sorted by Address.
pub fn new_backed_by_file(
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess this is mainly a forward looking comment, in the sense it doesn't necessarily fit in the scope of this PR, but it feels a bit redundant to have three constructors for GuestMemoryMmap, which also share quite a bit of logic (like the overlapping regions check). I think it would be neat to only keep from_regions, and then implement some helper logic in mmap_unix.rs (and the Windows one I guess) to simplify creating Vecs of regions (file backed or not), which can then be passed to from_regions. Just throwing this out there, what do you ppl think?

Copy link
Author

Choose a reason for hiding this comment

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

Yes I agree with this one, but let's do it in 2 steps if you don't mind. Let's first introduce the new possibility to create memory regions backed by a file, and then we can try to provide all features through a factorized function.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sure

Copy link
Member

Choose a reason for hiding this comment

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

Let's add the FileRange struct, and make this take a &[(GuestAddress, FileRange)].

Copy link
Author

Choose a reason for hiding this comment

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

@alexandruag will include it in its PR.

In order to support use cases where the memory needs to be backed by
actual files in order to be shared across processes (vhost-user case),
this patch introduces a new function creating the guest memory with
each region backed by a file descriptor provided by the caller.

It also introduces two helpers to retrieve file information related
to a region. Each file is owned by the memory region so that the
caller does not have to deal with ownership. This way, the file gets
to live as long as the memory region is active.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
/// Creates a container and allocates shared memory backed by a file for
/// guest memory regions. Valid memory regions are specified as a Vec of
/// (Address, Size, File, Offset) tuples sorted by Address.
pub fn new_backed_by_file(
Copy link
Member

Choose a reason for hiding this comment

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

Let's add the FileRange struct, and make this take a &[(GuestAddress, FileRange)].

@sboeuf
Copy link
Author

sboeuf commented Jun 26, 2019

Closing as superseded by #29 which got merged!

@sboeuf sboeuf closed this Jun 26, 2019
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.

5 participants