blob: b6dbc9356b32f5dc8b02e545a5824c9f2fcff850 [file] [log] [blame] [edit]
// 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.
@available(added=HEAD)
@discoverable
closed protocol Allocator {
/// Allocates a BufferCollection 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
/// BufferCollectionToken stage, so there's no way to allow another
/// participant to specify its constraints.
///
/// Real clients are encouraged to use AllocateSharedCollection() instead,
/// and to let relevant participants directly convey their own constraints to
/// sysmem.
///
/// `collection_request` is the server end of the BufferCollection FIDL
/// channel. The client can call SetConstraints() and then
/// WaitForBuffersAllocated() on the client end of this channel to specify
/// constraints and then determine success/failure and get the
/// BufferCollectionInfo_2 for the BufferCollection. The client should also
/// keep the client end of this channel open while using the
/// BufferCollection, and should notice when this channel closes and stop
/// using the BufferCollection ASAP.
strict AllocateNonSharedCollection(resource table {
1: collection_request server_end:BufferCollection;
});
/// Creates a logical BufferCollectionToken which can be shared among
/// participants (using BufferCollectionToken.Duplicate()), and then
/// converted into a BufferCollection using BindSharedCollection().
///
/// Success/failure to populate the BufferCollection with buffers is
/// determined via the BufferCollection interface.
strict AllocateSharedCollection(resource table {
1: token_request server_end:BufferCollectionToken;
});
/// Convert a BufferCollectionToken into a connection to the logical
/// BufferCollection. The BufferCollection hasn't yet been populated with
/// buffers - the participant must first also send SetConstraints() via the
/// client end of buffer_collection.
///
/// All BufferCollectionToken(s) duplicated from a logical
/// BufferCollectionToken created via AllocateSharedCollection() must be
/// turned in via BindSharedCollection() before the logical BufferCollection
/// will be populated with buffers.
///
/// `token` the client endpoint of a channel whose server end was sent to
/// sysmem using AllocateSharedCollection or whose server end was sent to
/// sysmem using BufferCollectionToken.Duplicate(). The token is being
/// "exchanged" for a channel to the logical BufferCollection.
///
/// `buffer_collection_request` the server end of a BufferCollection
/// channel. The sender retains the client end as usual. The
/// BufferCollection channel is a single participant's connection to the
/// logical BufferCollection. There typically will be other participants
/// with their own BufferCollection channel to the logical BufferCollection.
strict BindSharedCollection(resource table {
1: token client_end:BufferCollectionToken;
2: buffer_collection_request server_end:BufferCollection;
});
/// Validate that a BufferCollectionToken is known to the sysmem server.
///
/// This can be used in cases where BindSharedCollection() won't be called
/// until after BufferCollectionToken.Duplicate() +
/// BufferCollectionToken.Sync(), when the client code wants to know earlier
/// whether an incoming token is valid (so far).
///
/// Calling BufferCollectionToken.Sync() on a token that isn't known to
/// sysmem risks the Sync() hanging forever.
///
/// Given that an incoming token can become invalid at any time if any
/// participant drops their BufferCollectionToken(s) or BufferCollection(s),
/// authors of client code are encouraged to consider not calling
/// ValidateBufferCollectionToken() and instead dealing with async failure
/// of the BufferCollection.Sync() after all the
/// BufferCollectionToken.Duplicate() and BindSharedCollection() (before
/// sending any duplicate tokens to other processes).
///
/// Regardless of the result of this call, this call has no effect on the
/// token with the referenced koid.
///
/// A true result from this call doesn't guarantee that the token remains
/// valid for any duration afterwards.
///
/// Client code will zx_object_get_info() on the client's token handle,
/// passing ZX_INFO_HANDLE_BASIC and getting back the related_koid
/// which then gets passed to ValidateBufferCollectionToken().
///
/// If ValidateBufferCollectionToken() returns true, the token was known at
/// the time the sysmem server processed the call, but may no longer be
/// valid/known by the time the client code receives the response.
///
/// If ValidateBufferCollectionToken() returns false, the token wasn't known
/// at the time the sysmem server processed the call, but the token may
/// become known by the time the client code receives the response. However
/// client code is not required to mitigate the possibility that the token
/// may become known late, since the source of the token should have synced
/// the token to sysmem before sending the token to the client code.
///
/// If calling ValidateBufferCollectionToken() fails in some way, there will
/// be a zx_status_t from the FIDL layer.
///
/// `token_server_koid` the koid of the server end of a channel that might
/// be a BufferCollectionToken channel. This can be obtained from
/// zx_object_get_info() ZX_INFO_HANDLE_BASIC related_koid.
strict 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 debug leaking memory and hangs waiting for constraints. |name| can
/// be an arbitrary string, but the current process name (see
/// fsl::GetCurrentProcessName()) is a good default. |id| can be an
/// arbitrary id, but the current process ID (see
/// fsl::GetCurrentProcessKoid()) is a good default.
///
/// This information is propagated to all BufferCollections created using
/// BindSharedCollection() or AllocateNonSharedCollection() from this
/// allocator. It does not affect BufferCollectionTokens, since they are
/// often passed cross-process and should have their names managed manually.
strict SetDebugClientInfo(table {
1: name string:64;
2: id uint64;
});
/// Given a handle to a sysmem-provided VMO, this returns additional info
/// about the corresponding sysmem logical buffer, if any.
///
/// Most callers will want to keep their main handle to the VMO rather than
/// transferring it to sysmem via this call. Callers can duplicate their
/// main handle (ZX_RIGHT_SAME_RIGHTS) and send the duplicate.
///
/// On any error from this call (or at FIDL transport layer), the client
/// should not retry.
///
/// The client must check vmo_info.close_weak_asap and if that field is set,
/// the client must satisfy the rules specified in the comments on that
/// field. Failure to do so results in VMO leaks caused by the client and
/// loud complaints to the log by sysmem.
///
/// The number of distinct close_weak_asap object koids from repeated calls
/// to GetVmoInfo on the same input sysmem VMO is limited to a low constant.
///
/// 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.
///
/// Both strong and weak sysmem VMOs keep their info alive; 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).
///
/// Errors:
/// * ZX_ERR_NOT_FOUND - the vmo isn't a sysmem VMO.
/// * ZX_ERR_ACCESS_DENIED - the vmo isn't capable of being used with
/// GetVmoInfo due to rights/capability attenuation.
/// * ZX_ERR_INTERNAL - the request failed for an unspecified reason.
/// * ZX_ERR_INVALID_ARGS
strict 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 {
/// The buffer_collection_id is the unique ID of the logical buffer
/// collection. This ID is unique across all logical buffer collections,
/// per boot.
1: buffer_collection_id uint64;
/// The vmo's buffer_index is the index within the logical buffer
/// collection of which the vmo is a part. The buffer_collection_id and
/// buffer_index will be the same for all sysmem-delivered VMOs
/// corresponding to the same logical sysmem buffer, even if sysmem has
/// delivered child slice VMOs with different koid values (typically to
/// different clients). The buffer_index is only unique across logical
/// buffers in a collection; for a given logical buffer, the combination
/// of buffer_collection_id and buffer_index is unique per boot.
2: buffer_index uint64;
/// The close_weak_asap eventpair will be present iff the vmo handle is
/// "weak" from sysmem's point of view. This "weak" concept is a sysmem
/// concept, not a zircon concept. A single sysmem logical buffer can
/// have some "strong" VMO handles and some "weak" VMO handles. The
/// "strong" handles represent ownership; these handles represent a
/// direct justification for the logical buffer to continue to exist for
/// as long as these handles exist. The "weak" handles just represent
/// usage; these handles don't represent justification for the logical
/// buffer to continue to exist, but we need the client's
/// cooperation/participation to close the weak handle asap shortly
/// after all strong handles are gone.
///
/// All remaining handles to a weak sysmem VMO must be closed asap if
/// close_weak_asap signals ZX_EVENTPAIR_PEER_CLOSED, else the client
/// will likely be causing a VMO leak (the "weak"-ness only works with
/// the cooperation of all holders of weak sysmem VMO handles; we don't
/// remove the VMO's pages out from under the client's VMO handle(s)).
/// The ZX_EVENTPAIR_PEER_CLOSED will only be signaled when zero strong
/// sysmem VMO handles remain and zero strong BufferCollection
/// client_end(s) remain.
///
/// Then, once zero weak sysmem VMO(s) remain, the underlying logical
/// buffer's memory will be freed. This mechanism applies per
/// buffer_index in a collection, meaning that a logical buffer can be
/// freed even if another buffer in the same collection can't be freed
/// yet due to outstanding handles to strong or weak sysmem VMOs of that
/// other buffer.
///
/// Different close_weak_asap handles for the same logical buffer may
/// refer to different eventpair objects, but all will be signaled when
/// it's time for remaining VMO handles corresponding to the logical
/// buffer to be closed. The client is free to ignore/close any
/// extra/redundant close_weak_asap handles for the same logical buffer.
///
/// The close_weak_asap eventpair may already have
/// ZX_EVENTPAIR_PEER_CLOSED signalled before VmoInfo arrives at the
/// client, in which case the client must close all of its remaining
/// handles to the same VMO object asap; the client may do so by
/// noticing ZX_EVENTPAIR_PEER_CLOSED via this handle, or via a
/// different close_weak_asap eventpair corresponding to the same
/// logical sysem buffer (matching buffer_collection_id and matching
/// buffer_index).
///
/// If a client continues to hold (weak by definition) VMO handles of
/// the logical buffer after ZX_EVENTPAIR_PEER_CLOSED, after a while
/// sysmem will complain loudly to the log. There is intentionally no
/// way to disable that logging.
///
/// A client can choose to notice that this field is set and just close
/// any remaining VMO handles corresponding to the logical buffer asap
/// immediately and never need to wait for ZX_EVENTPAIR_PEER_CLOSED.
/// This may be the easiest way to satisfy the rules here if the client
/// is not expecting to ever need to hold sysmem weak VMO handles, aside
/// from noticing a weak sysmem VMO and failing cleanly in that case.
/// See also BufferCollection.SetWeakOk.
3: close_weak_asap zx.Handle:EVENTPAIR;
}) error zx.Status;
};