| // Copyright 2022 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| library fuchsia.sysmem2; |
| |
| using zx; |
| |
| /// Allocates system memory buffers. |
| /// |
| /// Epitaphs are not used in this protocol. |
| @available(added=19) |
| @discoverable |
| open protocol Allocator { |
| /// Allocates a buffer collection on behalf of a single client (aka |
| /// initiator) who is also the only participant (from the point of view of |
| /// sysmem). |
| /// |
| /// This call exists mainly for temp/testing purposes. This call skips the |
| /// [`fuchsia.sysmem2/BufferCollectionToken`] stage, so there's no way to |
| /// allow another participant to specify its constraints. |
| /// |
| /// Real clients are encouraged to use |
| /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`] instead, and to |
| /// let relevant participants directly convey their own constraints to |
| /// sysmem by sending `BufferCollectionToken`s to those participants. |
| /// |
| /// + request `collection_request` The server end of the |
| /// [`fuchsia.sysmem2/BufferCollection`]. |
| flexible AllocateNonSharedCollection(resource table { |
| 1: collection_request server_end:BufferCollection; |
| }); |
| |
| /// Creates a root [`fuchsia.sysmem2/BufferCollectionToken`]. |
| /// |
| /// The `BufferCollectionToken` can be "duplicated" for distribution to |
| /// participants by using |
| /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`]. Each |
| /// `BufferCollectionToken` can be converted into a |
| /// [`fuchsia.sysmem2.BufferCollection`] using |
| /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`]. |
| /// |
| /// Buffer constraints can be set via |
| /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`]. |
| /// |
| /// Success/failure to populate the buffer collection with buffers can be |
| /// determined from |
| /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`]. |
| /// |
| /// Closing the client end of a `BufferCollectionToken` or |
| /// `BufferCollection` (without `Release` first) will fail all client ends |
| /// in the same failure domain, which by default is all client ends of the |
| /// buffer collection. See |
| /// [`fuchsia.sysmem2/BufferCollection.SetDispensable`] and |
| /// [`fuchsia.sysmem2/BufferCollection.AttachToken`] for ways to create |
| /// separate failure domains within a buffer collection. |
| flexible AllocateSharedCollection(resource table { |
| 1: token_request server_end:BufferCollectionToken; |
| }); |
| |
| /// Convert a [`fuchsia.sysmem2/BufferCollectionToken`] into a |
| /// [`fuchsia.sysmem2/BufferCollection`]. |
| /// |
| /// At the time of sending this message, the buffer collection hasn't yet |
| /// been populated with buffers - the participant must first also send |
| /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] via the |
| /// `BufferCollection` client end. |
| /// |
| /// All `BufferCollectionToken`(s) duplicated from a root |
| /// `BufferCollectionToken` (created via `AllocateSharedCollection`) must be |
| /// "turned in" via `BindSharedCollection` (or `Release`ed), and all |
| /// existing `BufferCollection` client ends must have sent `SetConstraints` |
| /// before the logical BufferCollection will be populated with buffers (or |
| /// will fail if the overall set of constraints can't be satisfied). |
| /// |
| /// + request `token` The client endpoint of a channel whose server end was |
| /// sent to sysmem using |
| /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`] or whose server |
| /// end was sent to sysmem using |
| /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`]. The token is |
| /// being "turned in" in exchange for a |
| /// [`fuchsia.sysmem2/BufferCollection`]. |
| /// + request `buffer_collection_request` The server end of a |
| /// [`fuchsia.sysmem2/BufferCollection`] channel. The sender retains the |
| /// client end. The `BufferCollection` channel is a single participant's |
| /// connection to the logical buffer collection. Typically there will be |
| /// other participants with their own `BufferCollection` channel to the |
| /// logical buffer collection. |
| flexible BindSharedCollection(resource table { |
| 1: token client_end:BufferCollectionToken; |
| 2: buffer_collection_request server_end:BufferCollection; |
| }); |
| |
| /// Checks whether a [`fuchsia.sysmem2/BufferCollectionToken`] is known to |
| /// the sysmem server. |
| /// |
| /// With this call, the client can determine whether an incoming token is a |
| /// real sysmem token that is known to the sysmem server, without any risk |
| /// of getting stuck waiting forever on a potentially fake token to complete |
| /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] or |
| /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] (or any other two-way |
| /// FIDL message). In cases where the client trusts the source of the token |
| /// to provide a real token, this call is not typically needed outside of |
| /// debugging. |
| /// |
| /// If the validate fails sometimes but succeeds other times, the source of |
| /// the token may itself not be calling |
| /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] or |
| /// [`fuchsia.sysmem2/BufferCollection.Sync`] after creating/duplicating the |
| /// token but before sending the token to the current client. It may be more |
| /// convenient for the source to use |
| /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] to duplicate |
| /// token(s), since that call has the sync step built in. Or, the buffer |
| /// collection may be failing before this call is processed by the sysmem |
| /// server, as buffer collection failure cleans up sysmem's tracking of |
| /// associated tokens. |
| /// |
| /// This call has no effect on any token. |
| /// |
| /// + request `token_server_koid` The koid of the server end of a channel |
| /// that might be a BufferCollectionToken channel. This can be obtained |
| /// via `zx_object_get_info` `ZX_INFO_HANDLE_BASIC` `related_koid`. |
| /// - response `is_known` true means sysmem knew of the token at the time |
| /// sysmem processed the request, but doesn't guarantee that the token is |
| /// still valid by the time the client receives the reply. What it does |
| /// guarantee is that the token at least was a real token, so a two-way |
| /// call to the token won't stall forever (will fail or succeed fairly |
| /// quickly, not stall). This can already be known implicitly if the |
| /// source of the token can be trusted to provide a real token. A false |
| /// value means the token wasn't known to sysmem at the time sysmem |
| /// processed this call, but the token may have previously been valid, or |
| /// may yet become valid. Or if the sender of the token isn't trusted to |
| /// provide a real token, the token may be fake. It's the responsibility |
| /// of the sender to sync with sysmem to ensure that previously |
| /// created/duplicated token(s) are known to sysmem, before sending the |
| /// token(s) to other participants. |
| flexible ValidateBufferCollectionToken(table { |
| 1: token_server_koid zx.Koid; |
| }) -> (table { |
| 1: is_known bool; |
| }); |
| |
| /// Set information about the current client that can be used by sysmem to |
| /// help diagnose leaking memory and allocation stalls waiting for a |
| /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`]. |
| /// |
| /// This sets the debug client info on all [`fuchsia.sysmem2/Node`](s) |
| /// subsequently created by this this [`fuchsia.sysmem2/Allocator`] |
| /// including any [`fuchsia.sysmem2/BufferCollection`](s) created via |
| /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] (in the absence of |
| /// any prior call to [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`], |
| /// these `BufferCollection`(s) have the same initial debug client info as |
| /// the token turned in to create the `BufferCollection`). |
| /// |
| /// This info can be subsequently overridden on a per-`Node` basis by |
| /// sending [`fuchsia.sysmem2/Node.SetDebugClientInfo`]. |
| /// |
| /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per |
| /// `Allocator` is the most efficient way to ensure that all |
| /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info |
| /// set, and is also more efficient than separately sending the same debug |
| /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each |
| /// created [`fuchsia.sysmem2/Node`]. |
| /// |
| /// + request `name` This can be an arbitrary string, but the current |
| /// process name (see `fsl::GetCurrentProcessName`) is a good default. |
| /// + request `id` This can be an arbitrary id, but the current process ID |
| /// (see `fsl::GetCurrentProcessKoid`) is a good default. |
| flexible SetDebugClientInfo(table { |
| 1: name string:MAX_CLIENT_NAME_LENGTH; |
| 2: id uint64; |
| }); |
| |
| /// Given a handle to a sysmem-provided VMO, this returns additional info |
| /// about the corresponding sysmem logical buffer. |
| /// |
| /// Most callers will duplicate a VMO handle first and send the duplicate to |
| /// this call. |
| /// |
| /// If the client has created a child VMO of a sysmem-provided VMO, that |
| /// child VMO isn't considered a "sysmem VMO" for purposes of this call. |
| /// |
| /// + request `vmo` A handle to a sysmem-provided VMO (or see errors). |
| /// - response `buffer_collection_id` The buffer collection ID, which is |
| /// unique per logical buffer collection per boot. |
| /// - response `buffer_index` The buffer index of the buffer within the |
| /// buffer collection. This is the same as the index of the buffer within |
| /// [`fuchsia.sysmem2/BufferCollectionInfo.buffers`]. The `buffer_index` |
| /// is the same for all sysmem-delivered VMOs corresponding to the same |
| /// logical buffer, even if the VMO koids differ. The `buffer_index` is |
| /// only unique across buffers of a buffer collection. For a given buffer, |
| /// the combination of `buffer_collection_id` and `buffer_index` is unique |
| /// per boot. |
| /// - response `close_weak_asap` Iff `vmo` is a handle to a weak sysmem VMO, |
| /// the `close_weak_asap` field will be set in the response. This handle |
| /// will signal `ZX_EVENTPAIR_PEER_CLOSED` when all weak VMO handles to |
| /// the buffer should be closed as soon as possible. This is signalled |
| /// shortly after all strong sysmem VMOs to the buffer are closed |
| /// (including any held indirectly via strong `BufferCollectionToken` or |
| /// strong `BufferCollection`). Failure to close all weak sysmem VMO |
| /// handles to the buffer quickly upon `ZX_EVENTPAIR_PEER_CLOSED` is |
| /// considered a VMO leak caused by the client still holding a weak sysmem |
| /// VMO handle and results in loud complaints to the log by sysmem. The |
| /// buffers of a collection can be freed independently of each other. The |
| /// `ZX_EVENTPAIR_PEER_CLOSED` may already be signalled before the |
| /// response arrives at the client. A client that isn't prepared to handle |
| /// weak sysmem VMOs, on seeing this field set, can close all handles to |
| /// the buffer and fail any associated request. |
| /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` - the vmo isn't a sysmem |
| /// VMO. Both strong and weak sysmem VMOs can be passed to this call, and |
| /// the VMO handle passed in to this call itself keeps the VMO's info |
| /// alive for purposes of responding to this call. Because of this, |
| /// ZX_ERR_NOT_FOUND errors are unambiguous (even if there are no other |
| /// handles to the VMO when calling; even if other handles are closed |
| /// before the GetVmoInfo response arrives at the client). |
| /// * error `[fuchsia.sysmem2/Error.HANDLE_ACCESS_DENIED]` The vmo isn't |
| /// capable of being used with GetVmoInfo due to rights/capability |
| /// attenuation. The VMO needs to be usable with [`zx_vmo_get_info`] with |
| /// topic [`ZX_INFO_HANDLE_BASIC`]. |
| /// * error `[fuchsia.sysmem2/Error.UNSPECIFIED]` The request failed for an |
| /// unspecified reason. See the log for more info. |
| /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The vmo field |
| /// wasn't set, or there was some other problem with the request field(s). |
| flexible GetVmoInfo(resource table { |
| /// `vmo` is required to be set; ownership is transferred to the server |
| /// so in most cases a client will duplicate a handle and transfer the |
| /// duplicate via this field. |
| 1: vmo zx.Handle:VMO; |
| }) -> (resource table { |
| 1: buffer_collection_id uint64; |
| 2: buffer_index uint64; |
| 3: close_weak_asap zx.Handle:EVENTPAIR; |
| }) error Error; |
| }; |