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

[RFC] Add support for UFFD backed memory when restoring Firecracker VM from snapshot #1

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

acatangiu
Copy link
Owner

Reason for This PR

Allows Firecracker customers to better manage the VMs memory.

Description of Changes

Add new 'mem_backend_type' parameter that takes either:

  • File
  • UffdOverUDS
    as valid values.

Rename 'mem_file_path' to 'mem_backend_path'. Interpretation of this field depends on the value of 'mem_backend_type':

  • Path to file that contains the guest memory to be loaded,
  • Path to UDS where a custom page-fault handler process is listening and expecting a Uffd to be sent by Firecracker. The Uffd is used to handle Firecracker's guest memory page faults in this separate process.

When /snapshot/load specifies memory backend type as 'UffdOverUDS', Firecracker doesn't handle the memory file itself anymore and expects an external process to handle its guest memory page faults.

To do this, anonymous memory is mmapped as guest memory while keeping the original memory regions shape. Then a Uffd is created and each guest memory range is registered with the Uffd so that any page faults won't be handled by the kernel, but will come up as events on the Uffd.

Firecracker then sends the memory ranges descriptions/mappings along with the Uffd over a UnixDomainSocket specified in 'mem_backend_path' parameter on the API call.

It is expected that on the other side there is already a process listening for incoming connections. Once Firecracker's connection is accepted, Firecracker sends the mappings and Uffd. The receiving process is from now responsible for handling any pagefaults on the Uffd.

The communication medium is a UDS, the protocol is SOCK_STREAM and the encoding is JSON.

Example client also added

Add an example process that handles page-faults for Firecracker after a load snapshot operation.

This simple pf-handler simply populates full memory regions on page-faults belonging to those regions.

License Acceptance

By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license.

PR Checklist

[Author TODO: Meet these criteria.]
[Reviewer TODO: Verify that these criteria are met. Request changes if not]

  • All commits in this PR are signed (git commit -s).
  • The reason for this PR is clearly provided (issue no. or explanation).
  • The description of changes is clear and encompassing.
  • Any required documentation changes (code and docs) are included in this PR.
  • Any newly added unsafe code is properly documented.
  • Any API changes are reflected in firecracker/swagger.yaml.
  • Any user-facing changes are mentioned in CHANGELOG.md.
  • All added/changed functionality is tested.

Memory::restore now takes an optional &File and creates
file-backed memory or anonymous memory depending on the option.

Signed-off-by: Adrian Catangiu <[email protected]>
Add new 'mem_backend_type' parameter that takes either:
  - File
  - UffdOverUDS
as valid values.

Rename 'mem_file_path' to 'mem_backend_path'. Interpretation of this
field depends on the value of 'mem_backend_type':
  - Path to file that contains the guest memory to be loaded,
  - Path to UDS where a custom page-fault handler process is listening
    and expecting a Uffd to be sent by Firecracker. The Uffd is used
    to handle Firecracker's guest memory page faults in this separate
    process.

Add plumbing for the new API, the Uffd path is only a stub for now.

Signed-off-by: Adrian Catangiu <[email protected]>
When /snapshot/load specifies memory backend type as 'UffdOverUDS',
Firecracker doesn't handle the memory file itself anymore and expects
an external process to handle its guest memory page faults.

To do this, anonymous memory is mmapped as guest memory while keeping
the original memory regions shape. Then a Uffd is created and each
guest memory range is registered with the Uffd so that any page faults
won't be handled by the kernel, but will come up as events on the Uffd.

Firecracker then sends the memory ranges descriptions/mappings along
with the Uffd over a UnixDomainSocket specified in 'mem_backend_path'
parameter on the API call.

It is expected that on the other side there is already a process
listening for incoming connections. Once Firecracker's connection is
accepted, Firecracker sends the mappings and Uffd. The receiving
process is from now responsible for handling any pagefaults on the
Uffd.

The communication medium is a UDS, the protocol is SOCK_STREAM and the
encoding is JSON.

Signed-off-by: Adrian Catangiu <[email protected]>
In the happy case we can close the fd since the other process has it
open and is using it to serve us pages.
The problem is that if other process crashes/exits, firecracker
guest memory will simply revert to anon-mem behavior which would lead
to silent errors and UB.

If the fault serving process exits while we hold a copy of the FD as
well, the uffd will still be alive but with no one to serve faults
leading to guest freeze (which is an unfortunate, but explicit and
defined behavior).

Use mem::forget() to keep the uffd open in this process as well.

Signed-off-by: Adrian Catangiu <[email protected]>
Add an example process that handles page-faults for Firecracker
after a load snapshot operation.

This simple pf-handler simply populates full memory regions on
page-faults belonging to those regions.

Signed-off-by: Adrian Catangiu <[email protected]>
@acatangiu acatangiu self-assigned this Oct 4, 2021
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.

1 participant