blob: 5ef3b058069bf5c21b6ae181fbedf4d032499a6d [file] [log] [blame] [view] [edit]
# Sysmem overview
[Sysmem][sysmem] is a [FIDL][fidl] service that allocates shared memory for
use by multiple applications and hardware blocks. This document gives an
overview of its major features and what it provides to the system.
## Motivation
Modern systems have specialized hardware blocks that can perform operations
on data. Some examples of these blocks:
* Rendering computer graphics with a GPU.
* Encoding or decoding video with a hardware codec.
* Capturing high-quality photographs with a camera and DSP.
* Compositing images to a display using the display controller’s overlay
engine.
* Evaluating neural networks with a TPU.
Often, we want to create pipelines passing data between those separate
hardware blocks. Some examples:
* Decoding video with a hardware codec and compositing it to the display
together with user interface content rendered on the GPU.
* Applying a neural network to a live camera feed.
To do this efficiently and avoid copying, drivers and applications must agree
on the format data is in and where the data is located in memory. This
agreement allows the output of one unit to be used directly by the next.
Hardware units have strict constraints on these properties and also
preferences about which data layout will give the best performance.
Sysmem is a global service that can be fed constraints by applications and
allocate buffers such that all the constraints are met. If multiple formats
are supported, it can choose between them based on the expected performance.
Sysmem buffers are often used to represent images and sysmem has special
support for negotiating image formats. However the sysmem interface can also
be used for audio or any other type of data.
Sysmem does not manage the flow of data once buffers have been allocated.
Applications in a pipeline are responsible for coordinating between each
other to ensure synchronization.
## Allocation process (simplified)
1. [Participants](#participants) connect to the
[fuchsia.sysmem.Allocator][Allocator] service
1. One participant (called the initiator) creates an initial
[buffer collection token](#token).
1. That participant [duplicates] the token and sends the duplicate to other
participants.
1. Those participants can also duplicate and send tokens, recursively, until
all participants have received a token.
1. Each participant [binds][bind] its token to get a buffer collection.
1. Each participant [sets constraints][setconstraints] on the buffer collection
1. Sysmem chooses a format that can satisfy all the constraints. This can
only happen after every participant has bound its token and set constraints
on the collection.
1. Sysmem allocates a number of [buffers](#Buffers) using that format.
1. Participants retrieve the buffers from sysmem, as well as information
about the allocated format.
The information returned by sysmem is the set of constraints the image
formats in that buffer must satisfy.
At this point participants can use the buffers with the allocated format,
subject to pipeline-specific constraints on the flow of data between
participants. Since multiple image sizes may be usable from a buffer,
participants must work together to choose an image size before they can
determine the precise image format. This allows a pipeline to switch image
sizes on the fly without needing to reallocate buffers.
If a new participant needs to be added to an existing collection which has
already undergone constraint negotiation and allocation, a new token can be
[attached][AttachToken] to the buffer collection. The new participant's
constraints must be satisfied using the already-allocated buffer collection,
or the logical allocation (from the point of view of the new participant) fails.
To increase the chances that the new participant can be added successfully, one
of the participants present during initial allocation can mark a token
[dispensable][SetDispensable]. This allows the token to be used to specify
stand-in constraints so that the buffer collection will be able to later
accommodate a new participant with the same constraints.
## Buffer destruction
All references to a buffer must be removed before sysmem will destroy it and
allow the memory to be reused. These include:
* [Handles][handles] to the VMO.
* [CPU mappings][map] of the VMO.
* [Child VMOs][vmo_create_child] of the VMO.
* [Pins][pmt] of the VMO for use by hardware.
* [Channels][channel] to a Buffer Collection containing that VMOs.
## Glossary
### Buffers
A buffer represents a single image or other piece of memory an application
will work with. Sysmem currently uses one [VMO][vmo] per buffer. Clients can
[map][map] the memory onto the CPU or [pin][pmt] it to use it with a hardware
block.
### Participants
A participant is any application or driver that wants to access a buffer. All
participants must connect to sysmem to negotiate memory formats.
### Image formats
An [image format][ImageFormat] is the entire set of properties needed for a
client to interpret the memory as a set of pixels. For example, it includes
the pixel format, size in width and height, row pitch in bytes between rows,
and color space.
### Buffer settings
[Buffer settings][SingleBufferSettings] are a complete description of the
properties of a buffer. These include the caching information, and other
properties that participants may need to access the memory. For images the
buffer settings will also have an image format.
Buffer settings do not include the specific memory address, so multiple
different buffers may have the same buffer settings.
### Heaps
A [heap][HeapType] represents one specific type of memory on a system. A
system may have multiple heaps with different performance characteristics
from each other. Some heaps may only be usable from a subset of hardware
devices on a system.
Some heaps may not be accessible from the CPU. For those heaps, the VMO
representing a buffer cannot be used directly but is instead used as a key.
An application wishing to use the buffer must send its VMO handle to the heap
driver and the heap driver can return information about what memory to use.
Example heaps:
* Main system memory.
* VRAM on a discrete GPU.
* A carved-out area of system memory that's only usable by some pieces of
hardware.
### Constraints
[Constraints][constraints] specify the set of
[BufferSettings][SingleBufferSettings] that a participant is able to use.
Participants often specify multiple potential buffer settings in a single set
of constraints, which gives sysmem the flexibility to pick any of them and
reduces the risk that there are no settings that can satisfy the constraints
from all participants.
### Negotiation
Negotiation is the process where sysmem looks at all the constraints from
participants and chooses buffer settings that work for all of them. If
multiple settings could work, sysmem can use information about how clients
will use the buffer and the architecture of the system to choose the optimal
settings.
### Buffer collection
A [buffer collection][BufferCollection] is a set of multiple buffers with all
the same buffer settings. Sysmem allocates an entire buffer collection at
once. Multiple participants may have FIDL channels open to the same buffer
collection.
### Buffer collection token {#token}
A [token][BufferCollectionToken] is used in the initial stages of the
negotiation process before memory is allocated. Tokens can be duplicated and
passed between processes before finally being [bound][bind] to a buffer
collection.
[vmo]: /docs/reference/kernel_objects/vm_object.md
[sysmem]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem
[HeapType]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem#HeapType
[ImageFormat]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem#ImageFormat_2
[SingleBufferSettings]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem#SingleBufferSettings
[duplicates]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem#BufferCollectionToken.Duplicate
[Allocator]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem#Allocator
[BufferCollectionToken]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem#BufferCollectionToken
[BufferCollection]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem#BufferCollection
[channel]: /docs/reference/kernel_objects/channel.md
[pmt]: /docs/reference/kernel_objects/pinned_memory_token.md
[vmo_create_child]: /docs/reference/syscalls/vmo_create_child.md
[handles]: /docs/concepts/kernel/handles.md
[bind]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem#Allocator.BindSharedCollection
[setconstraints]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem#BufferCollection.SetConstraints
[fidl]: /docs/development/languages/fidl/README.md
[map]: /docs/reference/syscalls/vmar_map.md
[constraints]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem#BufferCollectionConstraints
[AttachToken]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem#BufferCollection.AttachToken
[SetDispensable]: https://fuchsia.dev/reference/fidl/fuchsia.sysmem#BufferCollectionToken.SetDispensable