Skip to content
Snippets Groups Projects
Commit 0739495f authored by Lyude Paul's avatar Lyude Paul
Browse files

rust/drm/kms: Introduce Connector<T> and ConnectorState<T>

We start off by introducing wrappers for the first important type of mode
object: a DRM display connector. This introduces Connector<T:
DriverConnector> and ConnectorState<T: DriverConnectorState>. Both
DriverConnector and DriverConnectorState must be implemented by KMS
drivers, and a driver may have as many implementations of these two traits
as it needs. This also introduces the general data pattern we'll be using
for all of the core mode objects that can be used in atomic commits.

It's important to note that both Connector<T> and ConnectorState<T> are
intended to be "subclassable". To explain what this means, we need to look
at how a DRM driver normally uses objects like DRM connectors.

Typically, a driver in C will define its connectors like so:

struct foo_connector {
  struct drm_connector base;
  int bar;
}

Note that we have a drm_connector struct embedded in foo_connector, but we
have data which comes after it which is defined by the driver. This is
important for a number of reasons: connectors can have their own mutexes
and various other hardware-specific information that a driver may want
access to at any time. The same goes for drm_connector_state, where drivers
will subclass this struct in the same way. It's worth noting as well that
it isn't uncommon for a driver to have multiple types of connectors, but
we'll handle in a later commit.

As a result, we've designed Connector<T> and ConnectorState<T> so that for
both types: a DRM driver can add custom data into the T. As well, there's
some basic limitations on how this data may be accessed:

* Data within the `DriverConnector` struct is pinned in order to allow
  mutexes and other structs which need pinning to be stored within it. As
  well, it is impossible to get a direct mutable reference to the data
  within DriverConnector - as there's no locks for doing so which would
  cause a race condition.
* Data within the `DriverConnectorState` struct is currently not pinned.
  While it's not unheard of for a driver to put something like a mutex in
  its atomic states, (VKMS actually does this in some spots) this quickly
  complicates things especially with nonblocking modesets - and doesn't
  really fit into the philosophy of an atomic state anyway. We may add
  support for this in the future later if this does end up being needed,
  but for now we hold back in order to make it much easier for drivers to
  access private data within the atomic state.
  As well, the functions we provide for converting to/from raw connector
  state pointers are notably different from many other rust types in the
  kernel. Instead of converting raw state pointers to raw ConnectorState<T>
  pointers, we allow for direct immutable and mutable references. The
  reason for this is that it makes accessing private driver data in the
  state much easier, and unlike Connector<T> - we can actually uphold
  all of the required data aliasing rules thanks to states only being
  mutable by a single thread before they've been swapped in.
  Note that currently, we don't provide a way to access said private data
  for ConnectorState<T> since allowing direct access to a &mut
  ConnectorState<T> could allow a caller to modify portions of
  drm_connector_state which are meant to be invariant throughout the
  lifetime of the connector state. We'll address this in the next few
  commits when we introduce the global atomic state type.

And finally - we introduce the following internal traits for the crate side
of things:

  * AsRawConnector - any type which can spit out a *mut
    bindings::drm_connector or be recovered from one
  * AsRawConnectorState - any type which can return a reference to a
    bindings::drm_connector_state
  * private::AsRawConnectorState - just methods for AsRawConnectorState
    that we don't want to be accessible to our users (since they could be
    used to introduce UB)
  * FromRawConnectorState - any type which can be recovered from a raw
    pointer to a bindings::drm_connector_state

The reason for having AsRawConnectorState and FromRawConnectorState as
separate traits unlike AsRawConnector is due to the fact that we'll
introduce objects later on which can be used as DRM connector states, but
cannot be directly derived from a *mut bindings::drm_connector_state
because they hold additional state or have additional side-effects.

Likewise, we'll also have other objects which can be used as raw DRM
connectors - hence AsRawConnector.

TODO: Make sure docs are consistent
parent 09945a93
No related branches found
No related tags found
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment