Userland interfaces

The DRM core exports several interfaces to applications, generallyintended to be used through corresponding libdrm wrapper functions. Inaddition, drivers export device-specific interfaces for use by userspacedrivers & device-aware applications through ioctls and sysfs files.

External interfaces include: memory mapping, context management, DMAoperations, AGP management, vblank control, fence management, memorymanagement, and output management.

Cover generic ioctls and sysfs layout here. We only need high-levelinfo, since man pages should cover the rest.

libdrm Device Lookup

BEWARE THE DRAGONS! MIND THE TRAPDOORS!

In an attempt to warn anyone else who’s trying to figure out what’s goingon here, I’ll try to summarize the story. First things first, let’s clear upthe names, because the kernel internals, libdrm and the ioctls are all nameddifferently:

  • GET_UNIQUE ioctl, implemented by drm_getunique is wrapped up in libdrmthrough the drmGetBusid function.

  • The libdrm drmSetBusid function is backed by the SET_UNIQUE ioctl. Allthat code is nerved in the kernel withdrm_invalid_op().

  • The internal set_busid kernel functions and driver callbacks areexclusively use by the SET_VERSION ioctl, because only drm 1.0 (which isnerved) allowed userspace to set the busid through the above ioctl.

  • Other ioctls and functions involved are named consistently.

For anyone wondering what’s the difference between drm 1.1 and 1.4: Correctlyhandling pci domains in the busid on ppc. Doing this correctly was onlyimplemented in libdrm in 2010, hence can’t be nerved yet. No one knows what’sspecial with drm 1.2 and 1.3.

Now the actual horror story of how device lookup in drm works. At large,there’s 2 different ways, either by busid, or by device driver name.

Opening by busid is fairly simple:

  1. First call SET_VERSION to make sure pci domains are handled properly. As aside-effect this fills out the unique name in the master structure.

  2. Call GET_UNIQUE to read out the unique name from the master structure,which matches the busid thanks to step 1. If it doesn’t, proceed to trythe next device node.

Opening by name is slightly different:

  1. Directly call VERSION to get the version and to match against the drivername returned by that ioctl. Note that SET_VERSION is not called, whichmeans the unique name for the master node just opening is _not_ filledout. This despite that with current drm device nodes are always bound toone device, and can’t be runtime assigned like with drm 1.0.

  2. Match driver name. If it mismatches, proceed to the next device node.

  3. Call GET_UNIQUE, and check whether the unique name has length zero (bychecking that the first byte in the string is 0). If that’s not the caselibdrm skips and proceeds to the next device node. Probably this is justcopypasta from drm 1.0 times where a set unique name meant that the driverwas in use already, but that’s just conjecture.

Long story short: To keep the open by name logic working, GET_UNIQUE must_not_ return a unique string when SET_VERSION hasn’t been called yet,otherwise libdrm breaks. Even when that unique string can’t ever change, andis totally irrelevant for actually opening the device because runtimeassignable device instances were only support in drm 1.0, which is long dead.But the libdrm code in drmOpenByName somehow survived, hence this can’t bebroken.

Primary Nodes, DRM Master and Authentication

structdrm_master is used to track groups of clients with openprimary device nodes. For everystructdrm_file which has had atleast once successfully became the device master (either through theSET_MASTER IOCTL, or implicitly through opening the primary device node whenno one else is the current master that time) there exists onedrm_master.This is noted indrm_file.is_master. All other clients have just a pointerto thedrm_master they are associated with.

In addition only onedrm_master can be the current master for adrm_device.It can be switched through the DROP_MASTER and SET_MASTER IOCTL, orimplicitly through closing/opening the primary device node. See alsodrm_is_current_master().

Clients can authenticate against the current master (if it matches their own)using the GETMAGIC and AUTHMAGIC IOCTLs. Together with exchanging masters,this allows controlled access to the device for an entire group of mutuallytrusted clients.

booldrm_is_current_master(structdrm_file*fpriv)

checks whetherpriv is the current master

Parameters

structdrm_file*fpriv

DRM file private

Description

Checks whetherfpriv is current master on its device. This decides whether aclient is allowed to run DRM_MASTER IOCTLs.

Most of the modern IOCTL which require DRM_MASTER are for kernel modesetting- the current master is assumed to own the non-shareable display hardware.

structdrm_master*drm_master_get(structdrm_master*master)

reference a master pointer

Parameters

structdrm_master*master

structdrm_master

Description

Increments the reference count ofmaster and returns a pointer tomaster.

structdrm_master*drm_file_get_master(structdrm_file*file_priv)

referencedrm_file.master offile_priv

Parameters

structdrm_file*file_priv

DRM file private

Description

Increments the reference count offile_priv’sdrm_file.master and returnsthedrm_file.master. Iffile_priv has nodrm_file.master, returns NULL.

Master pointers returned from this function should be unreferenced usingdrm_master_put().

voiddrm_master_put(structdrm_master**master)

unreference and clear a master pointer

Parameters

structdrm_master**master

pointer to a pointer ofstructdrm_master

Description

This decrements thedrm_master behindmaster and sets it to NULL.

structdrm_master

drm master structure

Definition:

struct drm_master {    struct kref refcount;    struct drm_device *dev;    char *unique;    int unique_len;    struct idr magic_map;    void *driver_priv;    struct drm_master *lessor;    int lessee_id;    struct list_head lessee_list;    struct list_head lessees;    struct idr leases;    struct idr lessee_idr;};

Members

refcount

Refcount for this master object.

dev

Link back to the DRM device

unique

Unique identifier: e.g. busid. Protected bydrm_device.master_mutex.

unique_len

Length of unique field. Protected bydrm_device.master_mutex.

magic_map

Map of used authentication tokens. Protected bydrm_device.master_mutex.

driver_priv

Pointer to driver-private information.

lessor

Lease grantor, only set if thisstructdrm_master represents alessee holding a lease of objects fromlessor. Full owners of thedevice have this set to NULL.

The lessor does not change once it’s set indrm_lease_create(), andeach lessee holds a reference to its lessor that it releases uponbeing destroyed indrm_lease_destroy().

See also thesection on display resource leasing.

lessee_id

ID for lessees. Owners (i.e.lessor is NULL) always have ID 0.Protected bydrm_device.mode_config’sdrm_mode_config.idr_mutex.

lessee_list

List entry of lessees oflessor, where they are linked tolessees.Not used for owners. Protected bydrm_device.mode_config’sdrm_mode_config.idr_mutex.

lessees

List of drm_masters leasing from this one. Protected bydrm_device.mode_config’sdrm_mode_config.idr_mutex.

This list is empty if no leases have been granted, or if all lesseeshave been destroyed. Since lessors are referenced by all theirlessees, this master cannot be destroyed unless the list is empty.

leases

Objects leased to this drm_master. Protected bydrm_device.mode_config’sdrm_mode_config.idr_mutex.

Objects are leased all together indrm_lease_create(), and areremoved all together when the lease is revoked.

lessee_idr

All lessees under this owner (only used wherelessor is NULL).Protected bydrm_device.mode_config’sdrm_mode_config.idr_mutex.

Description

Note that master structures are only relevant for the legacy/primary devicenodes, hence there can only be one per device, not one per drm_minor.

DRM Display Resource Leasing

DRM leases provide information about whether a DRM master may control a DRMmode setting object. This enables the creation of multiple DRM masters thatmanage subsets of display resources.

The original DRM master of a device ‘owns’ the available drm resources. Itmay create additional DRM masters and ‘lease’ resources which it controlsto the new DRM master. This gives the new DRM master control over theleased resources until the owner revokes the lease, or the new DRM masteris closed. Some helpful terminology:

  • An ‘owner’ is astructdrm_master that is not leasing objects fromanotherstructdrm_master, and hence ‘owns’ the objects. The owner can beidentified as thestructdrm_master for whichdrm_master.lessor is NULL.

  • A ‘lessor’ is astructdrm_master which is leasing objects to one or moreotherstructdrm_master. Currently, lessees are not allowed tocreate sub-leases, hence the lessor is the same as the owner.

  • A ‘lessee’ is astructdrm_master which is leasing objects from someotherstructdrm_master. Each lessee only leases resources from a singlelessor recorded indrm_master.lessor, and holds the set of objects thatit is leasing indrm_master.leases.

  • A ‘lease’ is a contract between the lessor and lessee that identifieswhich resources may be controlled by the lessee. All of the resourcesthat are leased must be owned by or leased to the lessor, and lessors arenot permitted to lease the same object to multiple lessees.

The set of objects anystructdrm_master ‘controls’ is limited to the setof objects it leases (for lessees) or all objects (for owners).

Objects not controlled by astructdrm_master cannot be modified throughthe various state manipulating ioctls, and any state reported back to userspace will be edited to make them appear idle and/or unusable. Forinstance, connectors always report ‘disconnected’, while encodersreport no possible crtcs or clones.

Since each lessee may lease objects from a single lessor, display resourceleases form a tree ofstructdrm_master. As lessees are currently notallowed to create sub-leases, the tree depth is limited to 1. All ofthese get activated simultaneously when the top level device owner changesthrough the SETMASTER or DROPMASTER IOCTL, sodrm_device.master points tothe owner at the top of the lease tree (i.e. thestructdrm_master for whichdrm_master.lessor is NULL). The full list of lessees that are leasingobjects from the owner can be searched via the owner’sdrm_master.lessee_idr.

Open-Source Userspace Requirements

The DRM subsystem has stricter requirements than most other kernel subsystems onwhat the userspace side for new uAPI needs to look like. This section hereexplains what exactly those requirements are, and why they exist.

The short summary is that any addition of DRM uAPI requires correspondingopen-sourced userspace patches, and those patches must be reviewed and ready formerging into a suitable and canonical upstream project.

GFX devices (both display and render/GPU side) are really complex bits ofhardware, with userspace and kernel by necessity having to work together reallyclosely. The interfaces, for rendering and modesetting, must be extremely wideand flexible, and therefore it is almost always impossible to precisely definethem for every possible corner case. This in turn makes it really practicallyinfeasible to differentiate between behaviour that’s required by userspace, andwhich must not be changed to avoid regressions, and behaviour which is only anaccidental artifact of the current implementation.

Without access to the full source code of all userspace users that means itbecomes impossible to change the implementation details, since userspace coulddepend upon the accidental behaviour of the current implementation in minutedetails. And debugging such regressions without access to source code is prettymuch impossible. As a consequence this means:

  • The Linux kernel’s “no regression” policy holds in practice only foropen-source userspace of the DRM subsystem. DRM developers are perfectly fineif closed-source blob drivers in userspace use the same uAPI as the opendrivers, but they must do so in the exact same way as the open drivers.Creative (ab)use of the interfaces will, and in the past routinely has, leadto breakage.

  • Any new userspace interface must have an open-source implementation asdemonstration vehicle.

The other reason for requiring open-source userspace is uAPI review. Since thekernel and userspace parts of a GFX stack must work together so closely, codereview can only assess whether a new interface achieves its goals by looking atboth sides. Making sure that the interface indeed covers the use-case fullyleads to a few additional requirements:

  • The open-source userspace must not be a toy/test application, but the realthing. Specifically it needs to handle all the usual error and corner cases.These are often the places where new uAPI falls apart and hence essential toassess the fitness of a proposed interface.

  • The userspace side must be fully reviewed and tested to the standards of thatuserspace project. For e.g. mesa this means piglit testcases and review on themailing list. This is again to ensure that the new interface actually gets thejob done. The userspace-side reviewer should also provide an Acked-by on thekernel uAPI patch indicating that they believe the proposed uAPI is sound andsufficiently documented and validated for userspace’s consumption.

  • The userspace patches must be against the canonical upstream, not some vendorfork. This is to make sure that no one cheats on the review and testingrequirements by doing a quick fork.

  • The kernel patch can only be merged after all the above requirements are met,but itmust be merged to either drm-next or drm-misc-nextbefore theuserspace patches land. uAPI always flows from the kernel, doing things theother way round risks divergence of the uAPI definitions and header files.

These are fairly steep requirements, but have grown out from years of sharedpain and experience with uAPI added hastily, and almost always regretted aboutjust as fast. GFX devices change really fast, requiring a paradigm shift andentire new set of uAPI interfaces every few years at least. Together with theLinux kernel’s guarantee to keep existing userspace running for 10+ years thisis already rather painful for the DRM subsystem, with multiple different uAPIsfor the same thing co-existing. If we add a few more complete mistakes into themix every year it would be entirely unmanageable.

Render nodes

DRM core provides multiple character-devices for user-space to use.Depending on which device is opened, user-space can perform a differentset of operations (mainly ioctls). The primary node is always createdand called card<num>. Additionally, a currently unused control node,called controlD<num> is also created. The primary node provides alllegacy operations and historically was the only interface used byuserspace. With KMS, the control node was introduced. However, theplanned KMS control interface has never been written and so the controlnode stays unused to date.

With the increased use of offscreen renderers and GPGPU applications,clients no longer require running compositors or graphics servers tomake use of a GPU. But the DRM API required unprivileged clients toauthenticate to a DRM-Master prior to getting GPU access. To avoid thisstep and to grant clients GPU access without authenticating, rendernodes were introduced. Render nodes solely serve render clients, thatis, no modesetting or privileged ioctls can be issued on render nodes.Only non-global rendering commands are allowed. If a driver supportsrender nodes, it must advertise it via the DRIVER_RENDER DRM drivercapability. If not supported, the primary node must be used for renderclients together with the legacy drmAuth authentication procedure.

If a driver advertises render node support, DRM core will create aseparate render node called renderD<num>. There will be one render nodeper device. No ioctls except PRIME-related ioctls will be allowed onthis node. Especially GEM_OPEN will be explicitly prohibited. For acomplete list of driver-independent ioctls that can be used on rendernodes, see the ioctls marked DRM_RENDER_ALLOW in drm_ioctl.c Rendernodes are designed to avoid the buffer-leaks, which occur if clientsguess the flink names or mmap offsets on the legacy interface.Additionally to this basic interface, drivers must mark theirdriver-dependent render-only ioctls as DRM_RENDER_ALLOW so renderclients can use them. Driver authors must be careful not to allow anyprivileged ioctls on render nodes.

With render nodes, user-space can now control access to the render nodevia basic file-system access-modes. A running graphics server whichauthenticates clients on the privileged primary/legacy node is no longerrequired. Instead, a client can open the render node and is immediatelygranted GPU access. Communication between clients (or servers) is donevia PRIME. FLINK from render node to legacy node is not supported. Newclients must not use the insecure FLINK interface.

Besides dropping all modeset/global ioctls, render nodes also drop theDRM-Master concept. There is no reason to associate render clients witha DRM-Master as they are independent of any graphics server. Besides,they must work without any running master, anyway. Drivers must be ableto run without a master object if they support render nodes. If, on theother hand, a driver requires shared state between clients which isvisible to user-space and accessible beyond open-file boundaries, theycannot support render nodes.

Device Hot-Unplug

Note

The following is the plan. Implementation is not there yet(2020 May).

Graphics devices (display and/or render) may be connected via USB (e.g.display adapters or docking stations) or Thunderbolt (e.g. eGPU). An enduser is able to hot-unplug this kind of devices while they are beingused, and expects that the very least the machine does not crash. Anydamage from hot-unplugging a DRM device needs to be limited as much aspossible and userspace must be given the chance to handle it if it wantsto. Ideally, unplugging a DRM device still lets a desktop continue torun, but that is going to need explicit support throughout the wholegraphics stack: from kernel and userspace drivers, through displayservers, via window system protocols, and in applications and libraries.

Other scenarios that should lead to the same are: unrecoverable GPUcrash, PCI device disappearing off the bus, or forced unbind of a driverfrom the physical device.

In other words, from userspace perspective everything needs to keep onworking more or less, until userspace stops using the disappeared DRMdevice and closes it completely. Userspace will learn of the devicedisappearance from the device removed uevent, ioctls returning ENODEV(or driver-specific ioctls returning driver-specific things), or open()returning ENXIO.

Only after userspace has closed all relevant DRM device and dmabuf filedescriptors and removed all mmaps, the DRM driver can tear down itsinstance for the device that no longer exists. If the same physicaldevice somehow comes back in the mean time, it shall be a new DRMdevice.

Similar to PIDs, chardev minor numbers are not recycled immediately. Anew DRM device always picks the next free minor number compared to theprevious one allocated, and wraps around when minor numbers areexhausted.

The goal raises at least the following requirements for the kernel anddrivers.

Requirements for KMS UAPI

  • KMS connectors must change their status to disconnected.

  • Legacy modesets and pageflips, and atomic commits, both real andTEST_ONLY, and any other ioctls either fail with ENODEV or fakesuccess.

  • Pending non-blocking KMS operations deliver the DRM events userspaceis expecting. This applies also to ioctls that faked success.

  • open() on a device node whose underlying device has disappeared willfail with ENXIO.

  • Attempting to create a DRM lease on a disappeared DRM device willfail with ENODEV. Existing DRM leases remain and work as listedabove.

Requirements for Render and Cross-Device UAPI

  • All GPU jobs that can no longer run must have their fencesforce-signalled to avoid inflicting hangs on userspace.The associated error code is ENODEV.

  • Some userspace APIs already define what should happen when the devicedisappears (OpenGL, GL ES:GL_KHR_robustness;Vulkan:VK_ERROR_DEVICE_LOST; etc.). DRM drivers are free to implement thisbehaviour the way they see best, e.g. returning failures indriver-specific ioctls and handling those in userspace drivers, orrely on uevents, and so on.

  • dmabuf which point to memory that has disappeared will either fail toimport with ENODEV or continue to be successfully imported if it wouldhave succeeded before the disappearance. See also about memory mapsbelow for already imported dmabufs.

  • Attempting to import a dmabuf to a disappeared device will either failwith ENODEV or succeed if it would have succeeded without thedisappearance.

  • open() on a device node whose underlying device has disappeared willfail with ENXIO.

Requirements for Memory Maps

Memory maps have further requirements that apply to both existing mapsand maps created after the device has disappeared. If the underlyingmemory disappears, the map is created or modified such that reads andwrites will still complete successfully but the result is undefined.This applies to both userspace mmap()’d memory and memory pointed to bydmabuf which might be mapped to other devices (cross-device dmabufimports).

Raising SIGBUS is not an option, because userspace cannot realisticallyhandle it. Signal handlers are global, which makes them extremelydifficult to use correctly from libraries like those that Mesa produces.Signal handlers are not composable, you can’t have different handlersfor GPU1 and GPU2 from different vendors, and a third handler formmapped regular files. Threads cause additional pain with signalhandling as well.

Device reset

The GPU stack is really complex and is prone to errors, from hardware bugs,faulty applications and everything in between the many layers. Some errorsrequire resetting the device in order to make the device usable again. Thissection describes the expectations for DRM and usermode drivers when adevice resets and how to propagate the reset status.

Device resets can not be disabled without tainting the kernel, which can lead tohanging the entire kernel through shrinkers/mmu_notifiers. Userspace role indevice resets is to propagate the message to the application and apply anyspecial policy for blocking guilty applications, if any. Corollary is thatdebugging a hung GPU context require hardware support to be able to preempt sucha GPU context while it’s stopped.

Kernel Mode Driver

The KMD is responsible for checking if the device needs a reset, and to performit as needed. Usually a hang is detected when a job gets stuck executing.

Propagation of errors to userspace has proven to be tricky since it goes inthe opposite direction of the usual flow of commands. Because of this vendorindependent error handling was added to the &dma_fence object, this way driverscan add an error code to their fences before signaling them. See functiondma_fence_set_error() on how to do this and for examples of error codes to use.

The DRM scheduler also allows setting error codes on all pending fences whenhardware submissions are restarted after an reset. Error codes are alsoforwarded from the hardware fence to the scheduler fence to bubble up errorsto the higher levels of the stack and eventually userspace.

Fence errors can be queried by userspace through the generic SYNC_IOC_FILE_INFOIOCTL as well as through driver specific interfaces.

Additional to setting fence errors drivers should also keep track of resets percontext, the DRM scheduler provides thedrm_sched_entity_error() function ashelper for this use case. After a reset, KMD should reject new commandsubmissions for affected contexts.

User Mode Driver

After command submission, UMD should check if the submission was accepted orrejected. After a reset, KMD should reject submissions, and UMD can issue anioctl to the KMD to check the reset status, and this can be checked more oftenif the UMD requires it. After detecting a reset, UMD will then proceed to reportit to the application using the appropriate API error code, as explained in thesection below about robustness.

Robustness

The only way to try to keep a graphical API context working after a reset is ifit complies with the robustness aspects of the graphical API that it is using.

Graphical APIs provide ways to applications to deal with device resets. However,there is no guarantee that the app will use such features correctly, and auserspace that doesn’t support robust interfaces (like a non-robustOpenGL context or API without any robustness support like libva) leave therobustness handling entirely to the userspace driver. There is no strongcommunity consensus on what the userspace driver should do in that case,since all reasonable approaches have some clear downsides.

OpenGL

Apps using OpenGL should use the available robust interfaces, like theextensionGL_ARB_robustness (orGL_EXT_robustness for OpenGL ES). Thisinterface tells if a reset has happened, and if so, all the context state isconsidered lost and the app proceeds by creating new ones. There’s no consensuson what to do to if robustness is not in use.

Vulkan

Apps using Vulkan should check forVK_ERROR_DEVICE_LOST for submissions.This error code means, among other things, that a device reset has happened andit needs to recreate the contexts to keep going.

Reporting causes of resets

Apart from propagating the reset through the stack so apps can recover, it’sreally useful for driver developers to learn more about what caused the reset inthe first place. For this, drivers can make use of devcoredump to store relevantinformation about the reset and send device wedged event withnone recoverymethod (as explained in “Device Wedging” chapter) to notify userspace, so thisinformation can be collected and added to user bug reports.

Device Wedging

Drivers can optionally make use of device wedged event (implemented asdrm_dev_wedged_event() in DRM subsystem), which notifies userspace of ‘wedged’(hanged/unusable) state of the DRM device through a uevent. This is usefulespecially in cases where the device is no longer operating as expected and hasbecome unrecoverable from driver context. Purpose of this implementation is toprovide drivers a generic way to recover the device with the help of userspaceintervention, without taking any drastic measures (like resetting orre-enumerating the full bus, on which the underlying physical device is sitting)in the driver.

A ‘wedged’ device is basically a device that is declared dead by the driverafter exhausting all possible attempts to recover it from driver context. Theuevent is the notification that is sent to userspace along with a hint aboutwhat could possibly be attempted to recover the device from userspace and bringit back to usable state. Different drivers may have different ideas of a‘wedged’ device depending on hardware implementation of the underlying physicaldevice, and hence the vendor agnostic nature of the event. It is up to thedrivers to decide when they see the need for device recovery and how they wantto recover from the available methods.

Driver prerequisites

The driver, before opting for recovery, needs to make sure that the ‘wedged’device doesn’t harm the system as a whole by taking care of the prerequisites.Necessary actions must include disabling DMA to system memory as well as anycommunication channels with other devices. Further, the driver must ensurethat all dma_fences are signalled and any device state that the core kernelmight depend on is cleaned up. All existing mmaps should be invalidated andpage faults should be redirected to a dummy page. Once the event is sent, thedevice must be kept in ‘wedged’ state until the recovery is performed. Newaccesses to the device (IOCTLs) should be rejected, preferably with an errorcode that resembles the type of failure the device has encountered. This willsignify the reason for wedging, which can be reported to the application ifneeded.

Recovery

Current implementation defines four recovery methods, out of which, driverscan use any one, multiple or none. Method(s) of choice will be sent in theuevent environment asWEDGED=<method1>[,..,<methodN>] in order of less tomore side-effects. See the sectionVendor Specific RecoveryforWEDGED=vendor-specific. If driver is unsure about recovery ormethod is unknown,WEDGED=unknown will be sent instead.

Userspace consumers can parse this event and attempt recovery as per thefollowing expectations.

Recovery method

Consumer expectations

none

optional telemetry collection

rebind

unbind + bind driver

bus-reset

unbind + bus reset/re-enumeration + bind

vendor-specific

vendor specific recovery method

unknown

consumer policy

The only exception to this isWEDGED=none, which signifies that the devicewas temporarily ‘wedged’ at some point but was recovered from driver contextusing device specific methods like reset. No explicit recovery is expected fromthe consumer in this case, but it can still take additional steps like gatheringtelemetry information (devcoredump, syslog). This is useful because the firsthang is usually the most critical one which can result in consequential hangs orcomplete wedging.

Vendor Specific Recovery

WhenWEDGED=vendor-specific is sent, it indicates that the device requiresa recovery procedure specific to the hardware vendor and is not one of thestandardized approaches.

WEDGED=vendor-specific may be used to indicate different cases within asingle vendor driver, each requiring a distinct recovery procedure.In such scenarios, the vendor driver must provide comprehensive documentationthat describes each case, include additional hints to identify specific case andoutline the corresponding recovery procedure. The documentation includes:

Case - A list of all cases that sends theWEDGED=vendor-specific recovery method.

Hints - Additional Information to assist the userspace consumer in identifying anddifferentiating between different cases. This can be exposed through sysfs, debugfs,traces, dmesg etc.

Recovery Procedure - Clear instructions and guidance for recovering each case.This may include userspace scripts, tools needed for the recovery procedure.

It is the responsibility of the admin/userspace consumer to identify the case andverify additional identification hints before attempting a recovery procedure.

Example: If the device uses the Xe driver, then userspace consumer should refer toXe Device Wedging for the detailed documentation.

Task information

The information about which application (if any) was involved in the devicewedging is useful for userspace if they want to notify the user about whathappened (e.g. the compositor display a message to the user “The <task name>caused a graphical error and the system recovered”) or to implement policies(e.g. the daemon may “ban” an task that keeps resetting the device). If the taskinformation is available, the uevent will display asPID=<pid> andTASK=<taskname>. Otherwise,PID andTASK will not appear in theevent string.

The reliability of this information is driver and hardware specific, and shouldbe taken with a caution regarding it’s precision. To have a big picture of whatreally happened, the devcoredump file provides much more detailed informationabout the device state and about the event.

Consumer prerequisites

It is the responsibility of the consumer to make sure that the device or itsresources are not in use by any process before attempting recovery. With IOCTLserroring out, all device memory should be unmapped and file descriptors shouldbe closed to prevent leaks or undefined behaviour. The idea here is to clear thedevice of all user context beforehand and set the stage for a clean recovery.

ForWEDGED=vendor-specific recovery method, it is the responsibility of theconsumer to check the driver documentation and the usecase before attemptinga recovery.

Example - rebind

Udev rule:

SUBSYSTEM=="drm", ENV{WEDGED}=="rebind", DEVPATH=="*/drm/card[0-9]",RUN+="/path/to/rebind.sh $env{DEVPATH}"

Recovery script:

#!/bin/shDEVPATH=$(readlink -f /sys/$1/device)DEVICE=$(basename $DEVPATH)DRIVER=$(readlink -f $DEVPATH/driver)echo -n $DEVICE > $DRIVER/unbindecho -n $DEVICE > $DRIVER/bind

Customization

Although basic recovery is possible with a simple script, consumers can definecustom policies around recovery. For example, if the driver supports multiplerecovery methods, consumers can opt for the suitable one depending on scenarioslike repeat offences or vendor specific failures. Consumers can also choose tohave the device available for debugging or telemetry collection and base theirrecovery decision on the findings. This is useful especially when the driver isunsure about recovery or method is unknown.

IOCTL Support on Device Nodes

First things first, driver private IOCTLs should only be needed for driverssupporting rendering. Kernel modesetting is all standardized, and extendedthrough properties. There are a few exceptions in some existing drivers,which define IOCTL for use by the display DRM master, but they all predateproperties.

Now if you do have a render driver you always have to support it throughdriver private properties. There’s a few steps needed to wire all the thingsup.

First you need to define the structure for your IOCTL in your driver privateUAPI header ininclude/uapi/drm/my_driver_drm.h:

struct my_driver_operation {        u32 some_thing;        u32 another_thing;};

Please make sure that you follow all the best practices fromDocumentation/process/botching-up-ioctls.rst. Note thatdrm_ioctl()automatically zero-extends structures, hence make sure you can add more stuffat the end, i.e. don’t put a variable sized array there.

Then you need to define your IOCTL number, using one ofDRM_IO(),DRM_IOR(),DRM_IOW() orDRM_IOWR(). It must start with the DRM_IOCTL_ prefix:

##define DRM_IOCTL_MY_DRIVER_OPERATION \    DRM_IOW(DRM_COMMAND_BASE, struct my_driver_operation)

DRM driver private IOCTL must be in the range from DRM_COMMAND_BASE toDRM_COMMAND_END. Finally you need an array ofstructdrm_ioctl_desc to wireup the handlers and set the access rights:

static const struct drm_ioctl_desc my_driver_ioctls[] = {    DRM_IOCTL_DEF_DRV(MY_DRIVER_OPERATION, my_driver_operation,            DRM_AUTH|DRM_RENDER_ALLOW),};

And then assign this to thedrm_driver.ioctls field in your driverstructure.

See the separate chapter onfile operations for howthe driver-specific IOCTLs are wired up.

Recommended IOCTL Return Values

In theory a driver’s IOCTL callback is only allowed to return very few errorcodes. In practice it’s good to abuse a few more. This section documents commonpractice within the DRM subsystem:

ENOENT:

Strictly this should only be used when a file doesn’t exist e.g. whencalling the open() syscall. We reuse that to signal any kind of objectlookup failure, e.g. for unknown GEM buffer object handles, unknown KMSobject handles and similar cases.

ENOSPC:

Some drivers use this to differentiate “out of kernel memory” from “outof VRAM”. Sometimes also applies to other limited gpu resources used forrendering (e.g. when you have a special limited compression buffer).Sometimes resource allocation/reservation issues in command submissionIOCTLs are also signalled through EDEADLK.

Simply running out of kernel/system memory is signalled through ENOMEM.

EPERM/EACCES:

Returned for an operation that is valid, but needs more privileges.E.g. root-only or much more common, DRM master-only operations returnthis when called by unpriviledged clients. There’s no cleardifference between EACCES and EPERM.

ENODEV:

The device is not present anymore or is not yet fully initialized.

EOPNOTSUPP:

Feature (like PRIME, modesetting, GEM) is not supported by the driver.

ENXIO:

Remote failure, either a hardware transaction (like i2c), but also usedwhen the exporting driver of a shared dma-buf or fence doesn’t support afeature needed.

EINTR:

DRM drivers assume that userspace restarts all IOCTLs. Any DRM IOCTL canreturn EINTR and in such a case should be restarted with the IOCTLparameters left unchanged.

EIO:

The GPU died and couldn’t be resurrected through a reset. Modesettinghardware failures are signalled through the “link status” connectorproperty.

EINVAL:

Catch-all for anything that is an invalid argument combination whichcannot work.

IOCTL also use other error codes like ETIME, EFAULT, EBUSY, ENOTTY but theirusage is in line with the common meanings. The above list tries to just documentDRM specific patterns. Note that ENOTTY has the slightly unintuitive meaning of“this IOCTL does not exist”, and is used exactly as such in DRM.

drm_ioctl_t

Typedef: DRM ioctl function type.

Syntax

typedefintdrm_ioctl_t(structdrm_device*dev,void*data,structdrm_file*file_priv)

Parameters

structdrm_device*dev

DRM device inode

void*data

private pointer of the ioctl call

structdrm_file*file_priv

DRM file this ioctl was made on

Description

This is the DRM ioctl typedef. Note thatdrm_ioctl() has alrady copieddatainto kernel-space, and will also copy it back, depending upon the read/writesettings in the ioctl command code.

drm_ioctl_compat_t

Typedef: compatibility DRM ioctl function type.

Syntax

typedefintdrm_ioctl_compat_t(structfile*filp,unsignedintcmd,unsignedlongarg)

Parameters

structfile*filp

file pointer

unsignedintcmd

ioctl command code

unsignedlongarg

DRM file this ioctl was made on

Description

Just atypedefto make declaring an array of compatibility handlers easier.New drivers shouldn’t screw up the structure layout for their ioctlstructures and hence never need this.

enumdrm_ioctl_flags

DRM ioctl flags

Constants

DRM_AUTH

This is for ioctl which are used for rendering, and require that thefile descriptor is either for a render node, or if it’s alegacy/primary node, then it must be authenticated.

DRM_MASTER

This must be set for any ioctl which can change the modeset ordisplay state. Userspace must call the ioctl through a primary node,while it is the active master.

Note that read-only modeset ioctl can also be called byunauthenticated clients, or when a master is not the currently activeone.

DRM_ROOT_ONLY

Anything that could potentially wreak a master file descriptor needsto have this flag set. Current that’s only for the SETMASTER andDROPMASTER ioctl, which e.g. logind can call to force a non-behavingmaster (display compositor) into compliance.

This is equivalent to callers with the SYSADMIN capability.

DRM_RENDER_ALLOW

This is used for all ioctl needed for rendering only, for driverswhich support render nodes. This should be all new render drivers,and hence it should be always set for any ioctl with DRM_AUTH set.Note though that read-only query ioctl might have this set, but havenot set DRM_AUTH because they do not require authentication.

Description

Various flags that can be set indrm_ioctl_desc.flags to control howuserspace can use a given ioctl.

structdrm_ioctl_desc

DRM driver ioctl entry

Definition:

struct drm_ioctl_desc {    unsigned int cmd;    enum drm_ioctl_flags flags;    drm_ioctl_t *func;    const char *name;};

Members

cmd

ioctl command number, without flags

flags

a bitmask ofenumdrm_ioctl_flags

func

handler for this ioctl

name

user-readable name for debug output

Description

For convenience it’s easier to create these using theDRM_IOCTL_DEF_DRV()macro.

DRM_IOCTL_DEF_DRV

DRM_IOCTL_DEF_DRV(ioctl,_func,_flags)

helper macro to fill out astructdrm_ioctl_desc

Parameters

ioctl

ioctl command suffix

_func

handler for the ioctl

_flags

a bitmask ofenumdrm_ioctl_flags

Description

Small helper macro to create astructdrm_ioctl_desc entry. The ioctlcommand number is constructed by prependingDRM_IOCTL\_ and passing thattoDRM_IOCTL_NR().

intdrm_noop(structdrm_device*dev,void*data,structdrm_file*file_priv)

DRM no-op ioctl implementation

Parameters

structdrm_device*dev

DRM device for the ioctl

void*data

data pointer for the ioctl

structdrm_file*file_priv

DRM file for the ioctl call

Description

This no-op implementation for drm ioctls is useful for deprecatedfunctionality where we can’t return a failure code because existing userspacechecks the result of the ioctl, but doesn’t care about the action.

Always returns successfully with 0.

intdrm_invalid_op(structdrm_device*dev,void*data,structdrm_file*file_priv)

DRM invalid ioctl implementation

Parameters

structdrm_device*dev

DRM device for the ioctl

void*data

data pointer for the ioctl

structdrm_file*file_priv

DRM file for the ioctl call

Description

This no-op implementation for drm ioctls is useful for deprecatedfunctionality where we really don’t want to allow userspace to call the ioctlany more. This is the case for old ums interfaces for drivers thattransitioned to kms gradually and so kept the old legacy tables around. Thisonly applies to radeon and i915 kms drivers, other drivers shouldn’t need touse this function.

Always fails with a return value of -EINVAL.

longdrm_ioctl(structfile*filp,unsignedintcmd,unsignedlongarg)

ioctl callback implementation for DRM drivers

Parameters

structfile*filp

file this ioctl is called on

unsignedintcmd

ioctl cmd number

unsignedlongarg

user argument

Description

Looks up the ioctl function in the DRM core and the driver dispatch table,stored indrm_driver.ioctls. It checks for necessary permission by callingdrm_ioctl_permit(), and dispatches to the respective function.

Return

Zero on success, negative error code on failure.

booldrm_ioctl_flags(unsignedintnr,unsignedint*flags)

Check for core ioctl and return ioctl permission flags

Parameters

unsignedintnr

ioctl number

unsignedint*flags

where to return the ioctl permission flags

Description

This ioctl is only used by the vmwgfx driver to augment the access checksdone by the drm core and insofar a pretty decent layering violation. Thisshouldn’t be used by any drivers.

Return

True if thenr corresponds to a DRM core ioctl number, false otherwise.

longdrm_compat_ioctl(structfile*filp,unsignedintcmd,unsignedlongarg)

32bit IOCTL compatibility handler for DRM drivers

Parameters

structfile*filp

file this ioctl is called on

unsignedintcmd

ioctl cmd number

unsignedlongarg

user argument

Description

Compatibility handler for 32 bit userspace running on 64 kernels. All actualIOCTL handling is forwarded todrm_ioctl(), while marshalling structures asappropriate. Note that this only handles DRM core IOCTLs, if the driver hasbotched IOCTL itself, it must handle those by wrapping this function.

Return

Zero on success, negative error code on failure.

Testing and validation

Testing Requirements for userspace API

New cross-driver userspace interface extensions, like new IOCTL, new KMSproperties, new files in sysfs or anything else that constitutes an API changeshould have driver-agnostic testcases in IGT for that feature, if such a testcan be reasonably made using IGT for the target hardware.

Validating changes with IGT

There’s a collection of tests that aims to cover the whole functionality ofDRM drivers and that can be used to check that changes to DRM drivers or thecore don’t regress existing functionality. This test suite is called IGT andits code and instructions to build and run can be found inhttps://gitlab.freedesktop.org/drm/igt-gpu-tools/.

Using VKMS to test DRM API

VKMS is a software-only model of a KMS driver that is useful for testingand for running compositors. VKMS aims to enable a virtual display withoutthe need for a hardware display capability. These characteristics made VKMSa perfect tool for validating the DRM core behavior and also support thecompositor developer. VKMS makes it possible to test DRM functions in avirtual machine without display, simplifying the validation of some of thecore changes.

To Validate changes in DRM API with VKMS, start setting the kernel: makesure to enable VKMS module; compile the kernel with the VKMS enabled andinstall it in the target machine. VKMS can be run in a Virtual Machine(QEMU, virtme or similar). It’s recommended the use of KVM with the minimumof 1GB of RAM and four cores.

It’s possible to run the IGT-tests in a VM in two ways:

  1. Use IGT inside a VM

  2. Use IGT from the host machine and write the results in a shared directory.

Following is an example of using a VM with a shared directory withthe host machine to run igt-tests. This example uses virtme:

$ virtme-run --rwdir /path/for/shared_dir --kdir=path/for/kernel/directory --mods=auto

Run the igt-tests in the guest machine. This example runs the ‘kms_flip’tests:

$ /path/for/igt-gpu-tools/scripts/run-tests.sh -p -s -t "kms_flip.*" -v

In this example, instead of building the igt_runner, Piglit is used(-p option). It creates an HTML summary of the test results and savesthem in the folder “igt-gpu-tools/results”. It executes only the igt-testsmatching the -t option.

Display CRC Support

DRM device drivers can provide to userspace CRC information of each frame asit reached a given hardware component (a CRC sampling “source”).

Userspace can control generation of CRCs in a given CRTC by writing to thefile dri/0/crtc-N/crc/control in debugfs, with N being theindex ofthe CRTC. Accepted values are source names (which aredriver-specific) and the “auto” keyword, which will let the driver select adefault source of frame CRCs for this CRTC.

Once frame CRC generation is enabled, userspace can capture them by readingthe dri/0/crtc-N/crc/data file. Each line in that file contains the framenumber in the first field and then a number of unsigned integer fieldscontaining the CRC data. Fields are separated by a single space and the numberof CRC fields is source-specific.

Note that though in some cases the CRC is computed in a specified way and onthe frame contents as supplied by userspace (eDP 1.3), in general the CRCcomputation is performed in an unspecified way and on frame contents that havebeen already processed in also an unspecified way and thus userspace cannotrely on being able to generate matching CRC values for the frame contents thatit submits. In this general case, the maximum userspace can do is to comparethe reported CRCs of frames that should have the same contents.

On the driver side the implementation effort is minimal, drivers only need toimplementdrm_crtc_funcs.set_crc_source anddrm_crtc_funcs.verify_crc_source.The debugfs files are automatically set up if those vfuncs are set. CRC samplesneed to be captured in the driver by callingdrm_crtc_add_crc_entry().Depending on the driver and HW requirements,drm_crtc_funcs.set_crc_sourcemay result in a commit (even a full modeset).

CRC results must be reliable across non-full-modeset atomic commits, so if acommit via DRM_IOCTL_MODE_ATOMIC would disable or otherwise interfere withCRC generation, then the driver must mark that commit as a full modeset(drm_atomic_crtc_needs_modeset() should return true). As a result, to ensureconsistent results, generic userspace must re-setup CRC generation after alegacy SETCRTC or an atomic commit with DRM_MODE_ATOMIC_ALLOW_MODESET.

intdrm_crtc_add_crc_entry(structdrm_crtc*crtc,boolhas_frame,uint32_tframe,uint32_t*crcs)

Add entry with CRC information for a frame

Parameters

structdrm_crtc*crtc

CRTC to which the frame belongs

boolhas_frame

whether this entry has a frame number to go with

uint32_tframe

number of the frame these CRCs are about

uint32_t*crcs

array of CRC values, with length matching #drm_crtc_crc.values_cnt

Description

For each frame, the driver polls the source of CRCs for new data and callsthis function to add them to the buffer from where userspace reads.

Debugfs Support

DRM_DEBUGFS_GPUVA_INFO

DRM_DEBUGFS_GPUVA_INFO(show,data)

drm_info_list entry to dump a GPU VA space

Parameters

show

thedrm_info_list’s show callback

data

driver private data

Description

Drivers should use this macro to define adrm_info_list entry to provide adebugfs file for dumping the GPU VA space regions and mappings.

For each DRM GPU VA space drivers should calldrm_debugfs_gpuva_info() fromtheirshow callback.

structdrm_info_list

debugfs info list entry

Definition:

struct drm_info_list {    const char *name;    int (*show)(struct seq_file*, void*);    u32 driver_features;    void *data;};

Members

name

file name

show

Show callback.seq_file->private will be set to thestructdrm_info_node corresponding to the instance of this info on a givenstructdrm_minor.

driver_features

Required driver features for this entry

data

Driver-private data, should not be device-specific.

Description

This structure represents a debugfs file to be created by the drmcore.

structdrm_info_node

Per-minor debugfs node structure

Definition:

struct drm_info_node {    struct drm_minor *minor;    const struct drm_info_list *info_ent;};

Members

minor

structdrm_minor for this node.

info_ent

template for this node.

Description

This structure represents a debugfs file, as an instantiation of astructdrm_info_list on astructdrm_minor.

FIXME:

No it doesn’t make a hole lot of sense that we duplicate debugfs entries forboth the render and the primary nodes, but that’s how this has organicallygrown. It should probably be fixed, with a compatibility link, if needed.

structdrm_debugfs_info

debugfs info list entry

Definition:

struct drm_debugfs_info {    const char *name;    int (*show)(struct seq_file*, void*);    u32 driver_features;    void *data;};

Members

name

File name

show

Show callback.seq_file->private will be set to thestructdrm_debugfs_entry corresponding to the instance of this infoon a givenstructdrm_device.

driver_features

Required driver features for this entry.

data

Driver-private data, should not be device-specific.

Description

This structure represents a debugfs file to be created by the drmcore.

structdrm_debugfs_entry

Per-device debugfs node structure

Definition:

struct drm_debugfs_entry {    struct drm_device *dev;    struct drm_debugfs_info file;    struct list_head list;};

Members

dev

structdrm_device for this node.

file

Template for this node.

list

Linked list of all device nodes.

Description

This structure represents a debugfs file, as an instantiation of astructdrm_debugfs_info on astructdrm_device.

intdrm_debugfs_gpuva_info(structseq_file*m,structdrm_gpuvm*gpuvm)

dump the given DRM GPU VA space

Parameters

structseq_file*m

pointer to theseq_file to write

structdrm_gpuvm*gpuvm

thedrm_gpuvm representing the GPU VA space

Description

Dumps the GPU VA mappings of a given DRM GPU VA manager.

For each DRM GPU VA space drivers should call this function from theirdrm_info_list’s show callback.

Return

0 on success, -ENODEV if thegpuvm is not initialized

voiddrm_debugfs_create_files(conststructdrm_info_list*files,intcount,structdentry*root,structdrm_minor*minor)

Initialize a given set of debugfs files for DRM minor

Parameters

conststructdrm_info_list*files

The array of files to create

intcount

The number of files given

structdentry*root

DRI debugfs dir entry.

structdrm_minor*minor

device minor number

Description

Create a given set of debugfs files represented by an array ofstructdrm_info_list in the given root directory. These files will be removedautomatically ondrm_debugfs_dev_fini().

voiddrm_debugfs_add_file(structdrm_device*dev,constchar*name,int(*show)(structseq_file*,void*),void*data)

Add a given file to the DRM device debugfs file list

Parameters

structdrm_device*dev

drm device for the ioctl

constchar*name

debugfs file name

int(*show)(structseq_file*,void*)

show callback

void*data

driver-private data, should not be device-specific

Description

Add a given file entry to the DRM device debugfs file list to be created ondrm_debugfs_init.

voiddrm_debugfs_add_files(structdrm_device*dev,conststructdrm_debugfs_info*files,intcount)

Add an array of files to the DRM device debugfs file list

Parameters

structdrm_device*dev

drm device for the ioctl

conststructdrm_debugfs_info*files

The array of files to create

intcount

The number of files given

Description

Add a given set of debugfs files represented by an array ofstructdrm_debugfs_info in the DRM device debugfs file list.

Sysfs Support

DRM provides very little additional support to drivers for sysfsinteractions, beyond just all the standard stuff. Drivers who want to exposeadditional sysfs properties and property groups can attach them at eitherdrm_device.dev ordrm_connector.kdev.

Registration is automatically handled when callingdrm_dev_register(), ordrm_connector_register() in case of hot-plugged connectors. Unregistration isalso automatically handled bydrm_dev_unregister() anddrm_connector_unregister().

voiddrm_sysfs_hotplug_event(structdrm_device*dev)

generate a DRM uevent

Parameters

structdrm_device*dev

DRM device

Description

Send a uevent for the DRM device specified bydev. Currently we onlyset HOTPLUG=1 in the uevent environment, but this could be expanded todeal with other types of events.

Any new uapi should be using thedrm_sysfs_connector_status_event()for uevents on connector status change.

voiddrm_sysfs_connector_hotplug_event(structdrm_connector*connector)

generate a DRM uevent for any connector change

Parameters

structdrm_connector*connector

connector which has changed

Description

Send a uevent for the DRM connector specified byconnector. This will senda uevent with the properties HOTPLUG=1 and CONNECTOR.

voiddrm_sysfs_connector_property_event(structdrm_connector*connector,structdrm_property*property)

generate a DRM uevent for connector property change

Parameters

structdrm_connector*connector

connector on which property changed

structdrm_property*property

connector property which has changed.

Description

Send a uevent for the specified DRM connector and property. Currently weset HOTPLUG=1 and connector id along with the attached property idrelated to the change.

intdrm_class_device_register(structdevice*dev)

register new device with the DRM sysfs class

Parameters

structdevice*dev

device to register

Description

Registers a newstructdevice within the DRM sysfs class. Essentially onlyused by ttm to have a place for its global settings. Drivers should never usethis.

voiddrm_class_device_unregister(structdevice*dev)

unregister device with the DRM sysfs class

Parameters

structdevice*dev

device to unregister

Description

Unregisters astructdevice from the DRM sysfs class. Essentially only usedby ttm to have a place for its global settings. Drivers should never usethis.

VBlank event handling

The DRM core exposes two vertical blank related ioctls:

DRM_IOCTL_WAIT_VBLANK

This takes astructdrm_wait_vblank structure as its argument, andit is used to block or request a signal when a specified vblankevent occurs.

DRM_IOCTL_MODESET_CTL

This was only used for user-mode-settind drivers around modesettingchanges to allow the kernel to update the vblank interrupt aftermode setting, since on many devices the vertical blank counter isreset to 0 at some point during modeset. Modern drivers should notcall this any more since with kernel mode setting it is a no-op.

Userspace API Structures

DRM exposes many UAPI and structure definitions to have a consistentand standardized interface with users.Userspace can refer to these structure definitions and UAPI formatsto communicate to drivers.

CRTC index

CRTC’s have both an object ID and an index, and they are not the same thing.The index is used in cases where a densely packed identifier for a CRTC isneeded, for instance a bitmask of CRTC’s. The member possible_crtcs ofstructdrm_mode_get_plane is an example.

DRM_IOCTL_MODE_GETRESOURCES populates a structure with an array ofCRTC ID’s, and the CRTC index is its position in this array.

structdrm_gem_close

Argument forDRM_IOCTL_GEM_CLOSE ioctl.

Definition:

struct drm_gem_close {    __u32 handle;    __u32 pad;};

Members

handle

Handle of the object to be closed.

pad

Padding.

Description

Releases the handle to an mm object.

structdrm_gem_flink

Argument forDRM_IOCTL_GEM_FLINK ioctl.

Definition:

struct drm_gem_flink {    __u32 handle;    __u32 name;};

Members

handle

Handle for the object being named.

name

Returned global name.

Description

Create a global name for an object, returning the name.

Note that the name does not hold a reference; when the objectis freed, the name goes away.

structdrm_gem_open

Argument forDRM_IOCTL_GEM_OPEN ioctl.

Definition:

struct drm_gem_open {    __u32 name;    __u32 handle;    __u64 size;};

Members

name

Name of object being opened.

handle

Returned handle for the object.

size

Returned size of the object

Description

Open an object using the global name, returning a handle and the size.

This handle (of course) holds a reference to the object, so the objectwill not go away until the handle is deleted.

structdrm_gem_change_handle

Argument forDRM_IOCTL_GEM_CHANGE_HANDLE ioctl.

Definition:

struct drm_gem_change_handle {    __u32 handle;    __u32 new_handle;};

Members

handle

The handle of a gem object.

new_handle

An available gem handle.

Description

This ioctl changes the handle of a GEM object to the specified one.The new handle must be unused. On success the old handle is closedand all further IOCTL should refer to the new handle only.Calls to DRM_IOCTL_PRIME_FD_TO_HANDLE will return the new handle.

DRM_CAP_DUMB_BUFFER

DRM_CAP_DUMB_BUFFER

Description

If set to 1, the driver supports creating dumb buffers via theDRM_IOCTL_MODE_CREATE_DUMB ioctl.

DRM_CAP_VBLANK_HIGH_CRTC

DRM_CAP_VBLANK_HIGH_CRTC

Description

If set to 1, the kernel supports specifying aCRTC indexin the high bits ofdrm_wait_vblank_request.type.

Starting kernel version 2.6.39, this capability is always set to 1.

DRM_CAP_DUMB_PREFERRED_DEPTH

DRM_CAP_DUMB_PREFERRED_DEPTH

Description

The preferred bit depth for dumb buffers.

The bit depth is the number of bits used to indicate the color of a singlepixel excluding any padding. This is different from the number of bits perpixel. For instance, XRGB8888 has a bit depth of 24 but has 32 bits perpixel.

Note that this preference only applies to dumb buffers, it’s irrelevant forother types of buffers.

DRM_CAP_DUMB_PREFER_SHADOW

DRM_CAP_DUMB_PREFER_SHADOW

Description

If set to 1, the driver prefers userspace to render to a shadow bufferinstead of directly rendering to a dumb buffer. For best speed, userspaceshould do streaming ordered memory copies into the dumb buffer and neverread from it.

Note that this preference only applies to dumb buffers, it’s irrelevant forother types of buffers.

DRM_CAP_PRIME

DRM_CAP_PRIME

Description

Bitfield of supported PRIME sharing capabilities. SeeDRM_PRIME_CAP_IMPORTandDRM_PRIME_CAP_EXPORT.

Starting from kernel version 6.6, bothDRM_PRIME_CAP_IMPORT andDRM_PRIME_CAP_EXPORT are always advertised.

PRIME buffers are exposed as dma-buf file descriptors.SeePRIME Buffer Sharing.

DRM_PRIME_CAP_IMPORT

DRM_PRIME_CAP_IMPORT

Description

If this bit is set inDRM_CAP_PRIME, the driver supports importing PRIMEbuffers via theDRM_IOCTL_PRIME_FD_TO_HANDLE ioctl.

Starting from kernel version 6.6, this bit is always set inDRM_CAP_PRIME.

DRM_PRIME_CAP_EXPORT

DRM_PRIME_CAP_EXPORT

Description

If this bit is set inDRM_CAP_PRIME, the driver supports exporting PRIMEbuffers via theDRM_IOCTL_PRIME_HANDLE_TO_FD ioctl.

Starting from kernel version 6.6, this bit is always set inDRM_CAP_PRIME.

DRM_CAP_TIMESTAMP_MONOTONIC

DRM_CAP_TIMESTAMP_MONOTONIC

Description

If set to 0, the kernel will report timestamps withCLOCK_REALTIME instructdrm_event_vblank. If set to 1, the kernel will report timestamps withCLOCK_MONOTONIC. Seeclock_gettime(2) for the definition of theseclocks.

Starting from kernel version 2.6.39, the default value for this capabilityis 1. Starting kernel version 4.15, this capability is always set to 1.

DRM_CAP_ASYNC_PAGE_FLIP

DRM_CAP_ASYNC_PAGE_FLIP

Description

If set to 1, the driver supportsDRM_MODE_PAGE_FLIP_ASYNC for legacypage-flips.

DRM_CAP_CURSOR_WIDTH

DRM_CAP_CURSOR_WIDTH

Description

TheCURSOR_WIDTH andCURSOR_HEIGHT capabilities return a validwidth x height combination for the hardware cursor. The intention is that ahardware agnostic userspace can query a cursor plane size to use.

Note that the cross-driver contract is to merely return a valid size;drivers are free to attach another meaning on top, eg. i915 returns themaximum plane size.

DRM_CAP_CURSOR_HEIGHT

DRM_CAP_CURSOR_HEIGHT

Description

SeeDRM_CAP_CURSOR_WIDTH.

DRM_CAP_ADDFB2_MODIFIERS

DRM_CAP_ADDFB2_MODIFIERS

Description

If set to 1, the driver supports supplying modifiers in theDRM_IOCTL_MODE_ADDFB2 ioctl.

DRM_CAP_PAGE_FLIP_TARGET

DRM_CAP_PAGE_FLIP_TARGET

Description

If set to 1, the driver supports theDRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE andDRM_MODE_PAGE_FLIP_TARGET_RELATIVE flags indrm_mode_crtc_page_flip_target.flags for theDRM_IOCTL_MODE_PAGE_FLIPioctl.

DRM_CAP_CRTC_IN_VBLANK_EVENT

DRM_CAP_CRTC_IN_VBLANK_EVENT

Description

If set to 1, the kernel supports reporting the CRTC ID indrm_event_vblank.crtc_id for theDRM_EVENT_VBLANK andDRM_EVENT_FLIP_COMPLETE events.

Starting kernel version 4.12, this capability is always set to 1.

DRM_CAP_SYNCOBJ

DRM_CAP_SYNCOBJ

Description

If set to 1, the driver supports sync objects. SeeDRM Sync Objects.

DRM_CAP_SYNCOBJ_TIMELINE

DRM_CAP_SYNCOBJ_TIMELINE

Description

If set to 1, the driver supports timeline operations on sync objects. SeeDRM Sync Objects.

DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP

DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP

Description

If set to 1, the driver supportsDRM_MODE_PAGE_FLIP_ASYNC for atomiccommits.

DRM_CLIENT_CAP_STEREO_3D

DRM_CLIENT_CAP_STEREO_3D

Description

If set to 1, the DRM core will expose the stereo 3D capabilities of themonitor by advertising the supported 3D layouts in the flags ofstructdrm_mode_modeinfo. SeeDRM_MODE_FLAG_3D_*.

This capability is always supported for all drivers starting from kernelversion 3.13.

DRM_CLIENT_CAP_UNIVERSAL_PLANES

DRM_CLIENT_CAP_UNIVERSAL_PLANES

Description

If set to 1, the DRM core will expose all planes (overlay, primary, andcursor) to userspace.

This capability has been introduced in kernel version 3.15. Starting fromkernel version 3.17, this capability is always supported for all drivers.

DRM_CLIENT_CAP_ATOMIC

DRM_CLIENT_CAP_ATOMIC

Description

If set to 1, the DRM core will expose atomic properties to userspace. Thisimplicitly enablesDRM_CLIENT_CAP_UNIVERSAL_PLANES andDRM_CLIENT_CAP_ASPECT_RATIO.

If the driver doesn’t support atomic mode-setting, enabling this capabilitywill fail with -EOPNOTSUPP.

This capability has been introduced in kernel version 4.0. Starting fromkernel version 4.2, this capability is always supported for atomic-capabledrivers.

DRM_CLIENT_CAP_ASPECT_RATIO

DRM_CLIENT_CAP_ASPECT_RATIO

Description

If set to 1, the DRM core will provide aspect ratio information in modes.SeeDRM_MODE_FLAG_PIC_AR_*.

This capability is always supported for all drivers starting from kernelversion 4.18.

DRM_CLIENT_CAP_WRITEBACK_CONNECTORS

DRM_CLIENT_CAP_WRITEBACK_CONNECTORS

Description

If set to 1, the DRM core will expose special connectors to be used forwriting back to memory the scene setup in the commit. The client must enableDRM_CLIENT_CAP_ATOMIC first.

This capability is always supported for atomic-capable drivers starting fromkernel version 4.19.

DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT

DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT

Description

Drivers for para-virtualized hardware (e.g. vmwgfx, qxl, virtio andvirtualbox) have additional restrictions for cursor planes (thusmaking cursor planes on those drivers not truly universal,) e.g.they need cursor planes to act like one would expect from a mousecursor and have correctly set hotspot properties.If this client cap is not set the DRM core will hide cursor plane onthose virtualized drivers because not setting it implies that theclient is not capable of dealing with those extra restictions.Clients which do set cursor hotspot and treat the cursor planelike a mouse cursor should set this property.The client must enableDRM_CLIENT_CAP_ATOMIC first.

Setting this property on drivers which do not special casecursor planes (i.e. non-virtualized drivers) will returnEOPNOTSUPP, which can be used by userspace to gaugerequirements of the hardware/drivers they’re running on.

This capability is always supported for atomic-capable virtualizeddrivers starting from kernel version 6.6.

DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE

DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE

Description

If set to 1 the DRM core will allow setting the COLOR_PIPELINEproperty on adrm_plane, as well as drm_colorop properties.

Setting of these plane properties will be rejected when this clientcap is set:- COLOR_ENCODING- COLOR_RANGE

The client must enableDRM_CLIENT_CAP_ATOMIC first.

structdrm_syncobj_eventfd

Definition:

struct drm_syncobj_eventfd {    __u32 handle;    __u32 flags;    __u64 point;    __s32 fd;    __u32 pad;};

Members

handle

syncobj handle.

flags

Zero to wait for the point to be signalled, orDRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE to wait for a fence to beavailable for the point.

point

syncobj timeline point (set to zero for binary syncobjs).

fd

Existing eventfd to sent events to.

pad

Must be zero.

Description

Register an eventfd to be signalled by a syncobj. The eventfd counter willbe incremented by one.

DRM_IOCTL_GEM_CLOSE

DRM_IOCTL_GEM_CLOSE

Close a GEM handle.

Description

GEM handles are not reference-counted by the kernel. User-space isresponsible for managing their lifetime. For example, if user-space importsthe same memory object twice on the same DRM file description, the same GEMhandle is returned by both imports, and user-space needs to ensureDRM_IOCTL_GEM_CLOSE is performed once only. The same situation can happenwhen a memory object is allocated, then exported and imported again on thesame DRM file description. TheDRM_IOCTL_MODE_GETFB2 IOCTL is an exceptionand always returns fresh new GEM handles even if an existing GEM handlealready refers to the same memory object before the IOCTL is performed.

DRM_IOCTL_PRIME_HANDLE_TO_FD

DRM_IOCTL_PRIME_HANDLE_TO_FD

Convert a GEM handle to a DMA-BUF FD.

Description

User-space setsdrm_prime_handle.handle with the GEM handle to export anddrm_prime_handle.flags, and gets back a DMA-BUF file descriptor indrm_prime_handle.fd.

The export can fail for any driver-specific reason, e.g. because export isnot supported for this specific GEM handle (but might be for others).

Support for exporting DMA-BUFs is advertised viaDRM_PRIME_CAP_EXPORT.

DRM_IOCTL_PRIME_FD_TO_HANDLE

DRM_IOCTL_PRIME_FD_TO_HANDLE

Convert a DMA-BUF FD to a GEM handle.

Description

User-space setsdrm_prime_handle.fd with a DMA-BUF file descriptor toimport, and gets back a GEM handle indrm_prime_handle.handle.drm_prime_handle.flags is unused.

If an existing GEM handle refers to the memory object backing the DMA-BUF,that GEM handle is returned. Therefore user-space which needs to handlearbitrary DMA-BUFs must have a user-space lookup data structure to manuallyreference-count duplicated GEM handles. For more information seeDRM_IOCTL_GEM_CLOSE.

The import can fail for any driver-specific reason, e.g. because import isonly supported for DMA-BUFs allocated on this DRM device.

Support for importing DMA-BUFs is advertised viaDRM_PRIME_CAP_IMPORT.

DRM_IOCTL_MODE_RMFB

DRM_IOCTL_MODE_RMFB

Remove a framebuffer.

Description

This removes a framebuffer previously added via ADDFB/ADDFB2. The IOCTLargument is a framebuffer object ID.

Warning: removing a framebuffer currently in-use on an enabled plane willdisable that plane. The CRTC the plane is linked to may also be disabled(depending on driver capabilities).

DRM_IOCTL_MODE_CREATE_DUMB

DRM_IOCTL_MODE_CREATE_DUMB

Create a new dumb buffer object.

Description

KMS dumb buffers provide a very primitive way to allocate a buffer objectsuitable for scanout and map it for software rendering. KMS dumb buffers arenot suitable for hardware-accelerated rendering nor video decoding. KMS dumbbuffers are not suitable to be displayed on any other device than the KMSdevice where they were allocated from. Also seeDumb Buffer Objects.

The IOCTL argument is astructdrm_mode_create_dumb.

User-space is expected to create a KMS dumb buffer via this IOCTL, then addit as a KMS framebuffer viaDRM_IOCTL_MODE_ADDFB and map it viaDRM_IOCTL_MODE_MAP_DUMB.

DRM_CAP_DUMB_BUFFER indicates whether this IOCTL is supported.DRM_CAP_DUMB_PREFERRED_DEPTH andDRM_CAP_DUMB_PREFER_SHADOW indicatedriver preferences for dumb buffers.

DRM_IOCTL_MODE_GETFB2

DRM_IOCTL_MODE_GETFB2

Get framebuffer metadata.

Description

This queries metadata about a framebuffer. User-space fillsdrm_mode_fb_cmd2.fb_id as the input, and the kernels fills the rest of thestructas the output.

If the client is DRM master or hasCAP_SYS_ADMIN,drm_mode_fb_cmd2.handleswill be filled with GEM buffer handles. Fresh new GEM handles are alwaysreturned, even if another GEM handle referring to the same memory objectalready exists on the DRM file description. The caller is responsible forremoving the new handles, e.g. via theDRM_IOCTL_GEM_CLOSE IOCTL. The samenew handle will be returned for multiple planes in case they use the samememory object. Planes are valid until one has a zero handle -- this can beused to compute the number of planes.

Otherwise,drm_mode_fb_cmd2.handles will be zeroed and planes are validuntil one has a zerodrm_mode_fb_cmd2.pitches.

If the framebuffer has a format modifier,DRM_MODE_FB_MODIFIERS will be setindrm_mode_fb_cmd2.flags anddrm_mode_fb_cmd2.modifier will contain themodifier. Otherwise, user-space must ignoredrm_mode_fb_cmd2.modifier.

To obtain DMA-BUF FDs for each plane without leaking GEM handles, user-spacecan export each handle viaDRM_IOCTL_PRIME_HANDLE_TO_FD, then immediatelyclose each unique handle viaDRM_IOCTL_GEM_CLOSE, making sure to notdouble-close handles which are specified multiple times in the array.

DRM_IOCTL_MODE_CLOSEFB

DRM_IOCTL_MODE_CLOSEFB

Close a framebuffer.

Description

This closes a framebuffer previously added via ADDFB/ADDFB2. The IOCTLargument is a framebuffer object ID.

This IOCTL is similar toDRM_IOCTL_MODE_RMFB, except it doesn’t disableplanes and CRTCs. As long as the framebuffer is used by a plane, it’s keptalive. When the plane no longer uses the framebuffer (because theframebuffer is replaced with another one, or the plane is disabled), theframebuffer is cleaned up.

This is useful to implement flicker-free transitions between two processes.

Depending on the threat model, user-space may want to ensure that theframebuffer doesn’t expose any sensitive user information: closedframebuffers attached to a plane can be read back by the next DRM master.

DRM_IOCTL_SET_CLIENT_NAME

DRM_IOCTL_SET_CLIENT_NAME

Attach a name to a drm_file

Description

Having a name allows for easier tracking and debugging.The length of the name (without null ending char) must be<= DRM_CLIENT_NAME_MAX_LEN.The call will fail if the name contains whitespaces or non-printable chars.

DRM_IOCTL_GEM_CHANGE_HANDLE

DRM_IOCTL_GEM_CHANGE_HANDLE

Move an object to a different handle

Description

Some applications (notably CRIU) need objects to have specific gem handles.This ioctl changes the object at one gem handle to use a new gem handle.

structdrm_event

Header for DRM events

Definition:

struct drm_event {    __u32 type;    __u32 length;};

Members

type

event type.

length

total number of payload bytes (including header).

Description

Thisstructis a header for events written back to user-space on the DRM FD.A read on the DRM FD will always only return complete events: e.g. if theread buffer is 100 bytes large and there are two 64 byte events pending,only one will be returned.

Event types 0 - 0x7fffffff are generic DRM events, 0x80000000 andup are chipset specific. Generic DRM events includeDRM_EVENT_VBLANK,DRM_EVENT_FLIP_COMPLETE andDRM_EVENT_CRTC_SEQUENCE.

DRM_EVENT_VBLANK

DRM_EVENT_VBLANK

vertical blanking event

Description

This event is sent in response toDRM_IOCTL_WAIT_VBLANK with the_DRM_VBLANK_EVENT flag set.

The event payload is astructdrm_event_vblank.

DRM_EVENT_FLIP_COMPLETE

DRM_EVENT_FLIP_COMPLETE

page-flip completion event

Description

This event is sent in response to an atomic commit or legacy page-flip withtheDRM_MODE_PAGE_FLIP_EVENT flag set.

The event payload is astructdrm_event_vblank.

DRM_EVENT_CRTC_SEQUENCE

DRM_EVENT_CRTC_SEQUENCE

CRTC sequence event

Description

This event is sent in response toDRM_IOCTL_CRTC_QUEUE_SEQUENCE.

The event payload is astructdrm_event_crtc_sequence.

structdrm_mode_modeinfo

Display mode information.

Definition:

struct drm_mode_modeinfo {    __u32 clock;    __u16 hdisplay;    __u16 hsync_start;    __u16 hsync_end;    __u16 htotal;    __u16 hskew;    __u16 vdisplay;    __u16 vsync_start;    __u16 vsync_end;    __u16 vtotal;    __u16 vscan;    __u32 vrefresh;    __u32 flags;    __u32 type;    char name[DRM_DISPLAY_MODE_LEN];};

Members

clock

pixel clock in kHz

hdisplay

horizontal display size

hsync_start

horizontal sync start

hsync_end

horizontal sync end

htotal

horizontal total size

hskew

horizontal skew

vdisplay

vertical display size

vsync_start

vertical sync start

vsync_end

vertical sync end

vtotal

vertical total size

vscan

vertical scan

vrefresh

approximate vertical refresh rate in Hz

flags

bitmask of misc. flags, see DRM_MODE_FLAG_* defines

type

bitmask of type flags, see DRM_MODE_TYPE_* defines

name

string describing the mode resolution

Description

This is the user-space API display mode information structure. For thekernel version seestructdrm_display_mode.

structdrm_mode_get_plane

Get plane metadata.

Definition:

struct drm_mode_get_plane {    __u32 plane_id;    __u32 crtc_id;    __u32 fb_id;    __u32 possible_crtcs;    __u32 gamma_size;    __u32 count_format_types;    __u64 format_type_ptr;};

Members

plane_id

Object ID of the plane whose information should beretrieved. Set by caller.

crtc_id

Object ID of the current CRTC.

fb_id

Object ID of the current fb.

possible_crtcs

Bitmask of CRTC’s compatible with the plane. CRTC’sare created and they receive an index, which corresponds to theirposition in the bitmask. Bit N corresponds toCRTC index N.

gamma_size

Never used.

count_format_types

Number of formats.

format_type_ptr

Pointer to__u32 array of formats that aresupported by the plane. These formats do not require modifiers.

Description

Userspace can perform a GETPLANE ioctl to retrieve information about aplane.

To retrieve the number of formats supported, setcount_format_types to zeroand call the ioctl.count_format_types will be updated with the value.

To retrieve these formats, allocate an array with the memory needed to storecount_format_types formats. Pointformat_type_ptr to this array and callthe ioctl again (withcount_format_types still set to the value returned inthe first ioctl call).

structdrm_mode_get_connector

Get connector metadata.

Definition:

struct drm_mode_get_connector {    __u64 encoders_ptr;    __u64 modes_ptr;    __u64 props_ptr;    __u64 prop_values_ptr;    __u32 count_modes;    __u32 count_props;    __u32 count_encoders;    __u32 encoder_id;    __u32 connector_id;    __u32 connector_type;    __u32 connector_type_id;    __u32 connection;    __u32 mm_width;    __u32 mm_height;    __u32 subpixel;    __u32 pad;};

Members

encoders_ptr

Pointer to__u32 array of object IDs.

modes_ptr

Pointer tostructdrm_mode_modeinfo array.

props_ptr

Pointer to__u32 array of property IDs.

prop_values_ptr

Pointer to__u64 array of property values.

count_modes

Number of modes.

count_props

Number of properties.

count_encoders

Number of encoders.

encoder_id

Object ID of the current encoder.

connector_id

Object ID of the connector.

connector_type

Type of the connector.

See DRM_MODE_CONNECTOR_* defines.

connector_type_id

Type-specific connector number.

This is not an object ID. This is a per-type connector number. Each(type, type_id) combination is unique across all connectors of a DRMdevice.

The (type, type_id) combination is not a stable identifier: thetype_id can change depending on the driver probe order.

connection

Status of the connector.

Seeenumdrm_connector_status.

mm_width

Width of the connected sink in millimeters.

mm_height

Height of the connected sink in millimeters.

subpixel

Subpixel order of the connected sink.

Seeenumsubpixel_order.

pad

Padding, must be zero.

Description

User-space can perform a GETCONNECTOR ioctl to retrieve information about aconnector. User-space is expected to retrieve encoders, modes and propertiesby performing this ioctl at least twice: the first time to retrieve thenumber of elements, the second time to retrieve the elements themselves.

To retrieve the number of elements, setcount_props andcount_encoders tozero, setcount_modes to 1, and setmodes_ptr to a temporarystructdrm_mode_modeinfo element.

To retrieve the elements, allocate arrays forencoders_ptr,modes_ptr,props_ptr andprop_values_ptr, then setcount_modes,count_props andcount_encoders to their capacity.

Performing the ioctl only twice may be racy: the number of elements may havechanged with a hotplug event in-between the two ioctls. User-space isexpected to retry the last ioctl until the number of elements stabilizes.The kernel won’t fill any array which doesn’t have the expected length.

Force-probing a connector

If thecount_modes field is set to zero and the DRM client is the currentDRM master, the kernel will perform a forced probe on the connector torefresh the connector status, modes and EDID. A forced-probe can be slow,might cause flickering and the ioctl will block.

User-space needs to force-probe connectors to ensure their metadata isup-to-date at startup and after receiving a hot-plug event. User-spacemay perform a forced-probe when the user explicitly requests it. User-spaceshouldn’t perform a forced-probe in other situations.

structdrm_mode_property_enum

Description for an enum/bitfield entry.

Definition:

struct drm_mode_property_enum {    __u64 value;    char name[DRM_PROP_NAME_LEN];};

Members

value

numeric value for thisenumentry.

name

symbolic name for thisenumentry.

Description

Seestructdrm_property_enum for details.

structdrm_mode_get_property

Get property metadata.

Definition:

struct drm_mode_get_property {    __u64 values_ptr;    __u64 enum_blob_ptr;    __u32 prop_id;    __u32 flags;    char name[DRM_PROP_NAME_LEN];    __u32 count_values;    __u32 count_enum_blobs;};

Members

values_ptr

Pointer to a__u64 array.

enum_blob_ptr

Pointer to astructdrm_mode_property_enum array.

prop_id

Object ID of the property which should be retrieved. Setby the caller.

flags

DRM_MODE_PROP_* bitfield. Seedrm_property.flags fora definition of the flags.

name

Symbolic property name. User-space should use this field torecognize properties.

count_values

Number of elements invalues_ptr.

count_enum_blobs

Number of elements inenum_blob_ptr.

Description

User-space can perform a GETPROPERTY ioctl to retrieve information about aproperty. The same property may be attached to multiple objects, see“Modeset Base Object Abstraction”.

The meaning of thevalues_ptr field changes depending on the property type.Seedrm_property.flags for more details.

Theenum_blob_ptr andcount_enum_blobs fields are only meaningful when theproperty has the typeDRM_MODE_PROP_ENUM orDRM_MODE_PROP_BITMASK. Forbackwards compatibility, the kernel will always setcount_enum_blobs tozero when the property has the typeDRM_MODE_PROP_BLOB. User-space mustignore these two fields if the property has a different type.

User-space is expected to retrieve values and enums by performing this ioctlat least twice: the first time to retrieve the number of elements, thesecond time to retrieve the elements themselves.

To retrieve the number of elements, setcount_values andcount_enum_blobsto zero, then call the ioctl.count_values will be updated with the numberof elements. If the property has the typeDRM_MODE_PROP_ENUM orDRM_MODE_PROP_BITMASK,count_enum_blobs will be updated as well.

To retrieve the elements themselves, allocate an array forvalues_ptr andsetcount_values to its capacity. If the property has the typeDRM_MODE_PROP_ENUM orDRM_MODE_PROP_BITMASK, allocate an array forenum_blob_ptr and setcount_enum_blobs to its capacity. Calling the ioctlagain will fill the arrays.

structdrm_mode_fb_cmd2

Frame-buffer metadata.

Definition:

struct drm_mode_fb_cmd2 {    __u32 fb_id;    __u32 width;    __u32 height;    __u32 pixel_format;    __u32 flags;    __u32 handles[4];    __u32 pitches[4];    __u32 offsets[4];    __u64 modifier[4];};

Members

fb_id

Object ID of the frame-buffer.

width

Width of the frame-buffer.

height

Height of the frame-buffer.

pixel_format

FourCC format code, seeDRM_FORMAT_* constants indrm_fourcc.h.

flags

Frame-buffer flags (seeDRM_MODE_FB_INTERLACED andDRM_MODE_FB_MODIFIERS).

handles

GEM buffer handle, one per plane. Set to 0 if the plane isunused. The same handle can be used for multiple planes.

pitches

Pitch (aka. stride) in bytes, one per plane.

offsets

Offset into the buffer in bytes, one per plane.

modifier

Format modifier, one per plane. SeeDRM_FORMAT_MOD_*constants indrm_fourcc.h. All planes must use the samemodifier. Ignored unlessDRM_MODE_FB_MODIFIERS is set inflags.

Description

Thisstructholds frame-buffer metadata. There are two ways to use it:

  • User-space can fill thisstructand perform aDRM_IOCTL_MODE_ADDFB2ioctl to register a new frame-buffer. The new frame-buffer object ID willbe set by the kernel infb_id.

  • User-space can setfb_id and perform aDRM_IOCTL_MODE_GETFB2 ioctl tofetch metadata about an existing frame-buffer.

In case of planar formats, thisstructallows up to 4 buffer objects withoffsets and pitches per plane. The pitch and offset order are dictated bythe format FourCC as defined bydrm_fourcc.h, e.g. NV12 is described as:

YUV 4:2:0 image with a plane of 8-bit Y samples followed by aninterleaved U/V plane containing 8-bit 2x2 subsampled colour differencesamples.

So it would consist of a Y plane atoffsets[0] and a UV plane atoffsets[1].

To accommodate tiled, compressed, etc formats, a modifier can be specified.For more information see the “Format Modifiers” section. Note that eventhough it looks like we have a modifier per-plane, we in fact do not. Themodifier for each plane must be identical. Thus all combinations ofdifferent data layouts for multi-plane formats must be enumerated asseparate modifiers.

All of the entries inhandles,pitches,offsets andmodifier must bezero when unused. Warning, foroffsets andmodifier zero can’t be used tofigure out whether the entry is used or not since it’s a valid value (a zerooffset is common, and a zero modifier isDRM_FORMAT_MOD_LINEAR).

enumdrm_colorop_type

Type of color operation

Constants

DRM_COLOROP_1D_CURVE

enumstring “1D Curve”

A 1D curve that is being applied to all color channels. Thecurve is specified via the CURVE_1D_TYPE colorop property.

DRM_COLOROP_1D_LUT

enumstring “1D LUT”

A simple 1D LUT of uniformly spaceddrm_color_lut32 entries,packed into a blob via the DATA property. The driver’sexpected LUT size is advertised via the SIZE property.

The DATA blob is an array ofstructdrm_color_lut32 with sizeof “size”.

DRM_COLOROP_CTM_3X4

enumstring “3x4 Matrix”

A 3x4 matrix. Its values are specified via thedrm_color_ctm_3x4structprovided via the DATA property.

The DATA blob is a float[12]:out matrix in| R | | 0 1 2 3 | | R || G | = | 4 5 6 7 | x | G || B | | 8 9 10 12 | | B |

DRM_COLOROP_MULTIPLIER

enumstring “Multiplier”

A simple multiplier, applied to all color values. Themultiplier is specified as a S31.32 via the MULTIPLIERproperty.

DRM_COLOROP_3D_LUT

enumstring “3D LUT”

A 3D LUT ofdrm_color_lut32 entries,packed into a blob via the DATA property. The driver’s expectedLUT size is advertised via the SIZE property, i.e., a 3D LUT with17x17x17 entries will have SIZE set to 17.

The DATA blob is a 3D array ofstructdrm_color_lut32 with dimensionlength of “size”.The LUT elements are traversed like so:

for B in range 0..n
for G in range 0..n
for R in range 0..n
index = R + n * (G + n * B)

color = lut3d[index]

Description

drm_colorops can be of many different types. Each type behaves differentlyand defines a different set of properties. Thisenumdefines all types andgives a high-level description.

enumdrm_colorop_lut3d_interpolation_type

type of 3DLUT interpolation

Constants

DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL

Tetrahedral 3DLUT interpolation

enumdrm_colorop_lut1d_interpolation_type

type of interpolation for 1D LUTs

Constants

DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR

Linear interpolation. Values between points of the LUT will belinearly interpolated.

structdrm_plane_size_hint

Plane size hints

Definition:

struct drm_plane_size_hint {    __u16 width;    __u16 height;};

Members

width

The width of the plane in pixel

height

The height of the plane in pixel

Description

The plane SIZE_HINTS property blob contains anarray ofstructdrm_plane_size_hint.

structhdr_metadata_infoframe

HDR Metadata Infoframe Data.

Definition:

struct hdr_metadata_infoframe {    __u8 eotf;    __u8 metadata_type;    struct {        __u16 x, y;    } display_primaries[3];    struct {        __u16 x, y;    } white_point;    __u16 max_display_mastering_luminance;    __u16 min_display_mastering_luminance;    __u16 max_cll;    __u16 max_fall;};

Members

eotf

Electro-Optical Transfer Function (EOTF)used in the stream.

metadata_type

Static_Metadata_Descriptor_ID.

display_primaries

Color Primaries of the Data.These are coded as unsigned 16-bit values in units of0.00002, where 0x0000 represents zero and 0xC350represents 1.0000.display_primaries.x: X coordinate of color primary.display_primaries.y: Y coordinate of color primary.

white_point

White Point of Colorspace Data.These are coded as unsigned 16-bit values in units of0.00002, where 0x0000 represents zero and 0xC350represents 1.0000.white_point.x: X coordinate of whitepoint of color primary.white_point.y: Y coordinate of whitepoint of color primary.

max_display_mastering_luminance

Max Mastering Display Luminance.This value is coded as an unsigned 16-bit value in units of 1 cd/m2,where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.

min_display_mastering_luminance

Min Mastering Display Luminance.This value is coded as an unsigned 16-bit value in units of0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFFrepresents 6.5535 cd/m2.

max_cll

Max Content Light Level.This value is coded as an unsigned 16-bit value in units of 1 cd/m2,where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.

max_fall

Max Frame Average Light Level.This value is coded as an unsigned 16-bit value in units of 1 cd/m2,where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.

Description

HDR Metadata Infoframe as per CTA 861.G spec. This is expectedto match exactly with the spec.

Userspace is expected to pass the metadata information as perthe format described in this structure.

structhdr_output_metadata

HDR output metadata

Definition:

struct hdr_output_metadata {    __u32 metadata_type;    union {        struct hdr_metadata_infoframe hdmi_metadata_type1;    };};

Members

metadata_type

Static_Metadata_Descriptor_ID.

{unnamed_union}

anonymous

hdmi_metadata_type1

HDR Metadata Infoframe.

Description

Metadata Information to be passed from userspace

DRM_MODE_PAGE_FLIP_EVENT

DRM_MODE_PAGE_FLIP_EVENT

Description

Request that the kernel sends back a vblank event (seestructdrm_event_vblank) with theDRM_EVENT_FLIP_COMPLETE type when thepage-flip is done.

When used with atomic uAPI, one event will be delivered per CRTC included inthe atomic commit. A CRTC is included in an atomic commit if one of itsproperties is set, or if a property is set on a connector or plane linkedvia the CRTC_ID property to the CRTC. At least one CRTC must be included,and all pulled in CRTCs must be either previously or newly powered on (inother words, a powered off CRTC which stays off cannot be included in theatomic commit).

DRM_MODE_PAGE_FLIP_ASYNC

DRM_MODE_PAGE_FLIP_ASYNC

Description

Request that the page-flip is performed as soon as possible, ie. with nodelay due to waiting for vblank. This may cause tearing to be visible onthe screen.

When used with atomic uAPI, the driver will return an error if the hardwaredoesn’t support performing an asynchronous page-flip for this update.User-space should handle this, e.g. by falling back to a regular page-flip.

Note, some hardware might need to perform one last synchronous page-flipbefore being able to switch to asynchronous page-flips. As an exception,the driver will return success even though that first page-flip is notasynchronous.

DRM_MODE_PAGE_FLIP_FLAGS

DRM_MODE_PAGE_FLIP_FLAGS

Description

Bitmask of flags suitable fordrm_mode_crtc_page_flip_target.flags.

structdrm_mode_create_dumb

Create a KMS dumb buffer for scanout.

Definition:

struct drm_mode_create_dumb {    __u32 height;    __u32 width;    __u32 bpp;    __u32 flags;    __u32 handle;    __u32 pitch;    __u64 size;};

Members

height

buffer height in pixels

width

buffer width in pixels

bpp

color mode

flags

must be zero

handle

buffer object handle

pitch

number of bytes between two consecutive lines

size

size of the whole buffer in bytes

Description

User-space fillsheight,width,bpp andflags. If the IOCTL succeeds,the kernel fillshandle,pitch andsize.

The value ofbpp is a color-mode number describing a specific formator a variant thereof. The value often corresponds to the number of bitsper pixel for most modes, although there are exceptions. Each color modemaps to a DRM format plus a number of modes with similar pixel layout.Framebuffer layout is always linear.

Support for all modes and formats is optional. Even if dumb-buffercreation with a certain color mode succeeds, it is not guaranteed thatthe DRM driver supports any of the related formats. Most drivers supporta color mode of 32 with a format of DRM_FORMAT_XRGB8888 on their primaryplane.

Color mode

Framebuffer format

Compatible formats

32

  • DRM_FORMAT_XRGB8888

  • DRM_FORMAT_BGRX8888

  • DRM_FORMAT_RGBX8888

  • DRM_FORMAT_XBGR8888

24

  • DRM_FORMAT_RGB888

  • DRM_FORMAT_BGR888

16

  • DRM_FORMAT_RGB565

  • DRM_FORMAT_BGR565

15

  • DRM_FORMAT_XRGB1555

  • DRM_FORMAT_BGRX1555

  • DRM_FORMAT_RGBX1555

  • DRM_FORMAT_XBGR1555

8

  • DRM_FORMAT_C8

  • DRM_FORMAT_D8

  • DRM_FORMAT_R8

4

  • DRM_FORMAT_C4

  • DRM_FORMAT_D4

  • DRM_FORMAT_R4

2

  • DRM_FORMAT_C2

  • DRM_FORMAT_D2

  • DRM_FORMAT_R2

1

  • DRM_FORMAT_C1

  • DRM_FORMAT_D1

  • DRM_FORMAT_R1

Color modes of 10, 12, 15, 30 and 64 are only supported for use bylegacy user space. Please don’t use them in new code. Other modesare not support.

Do not attempt to allocate anything but linear framebuffer memorywith single-plane RGB data. Allocation of other framebufferlayouts requires dedicated ioctls in the respective DRM driver.

DRM_MODE_ATOMIC_TEST_ONLY

DRM_MODE_ATOMIC_TEST_ONLY

Description

Do not apply the atomic commit, instead check whether the hardware supportsthis configuration.

Seedrm_mode_config_funcs.atomic_check for more details on test-onlycommits.

DRM_MODE_ATOMIC_NONBLOCK

DRM_MODE_ATOMIC_NONBLOCK

Description

Do not block while applying the atomic commit. TheDRM_IOCTL_MODE_ATOMICIOCTL returns immediately instead of waiting for the changes to be appliedin hardware. Note, the driver will still check that the update can beapplied before retuning.

DRM_MODE_ATOMIC_ALLOW_MODESET

DRM_MODE_ATOMIC_ALLOW_MODESET

Description

Allow the update to result in temporary or transient visible artifacts whilethe update is being applied. Applying the update may also take significantlymore time than a page flip. All visual artifacts will disappear by the timethe update is completed, as signalled through the vblank event’s timestamp(seestructdrm_event_vblank).

This flag must be set when the KMS update might cause visible artifacts.Without this flag such KMS update will return a EINVAL error. What kind ofupdate may cause visible artifacts depends on the driver and the hardware.User-space that needs to know beforehand if an update might cause visibleartifacts can useDRM_MODE_ATOMIC_TEST_ONLY withoutDRM_MODE_ATOMIC_ALLOW_MODESET to see if it fails.

To the best of the driver’s knowledge, visual artifacts are guaranteed tonot appear when this flag is not set. Some sinks might display visualartifacts outside of the driver’s control.

DRM_MODE_ATOMIC_FLAGS

DRM_MODE_ATOMIC_FLAGS

Description

Bitfield of flags accepted by theDRM_IOCTL_MODE_ATOMIC IOCTL indrm_mode_atomic.flags.

structdrm_mode_create_blob

Create New blob property

Definition:

struct drm_mode_create_blob {    __u64 data;    __u32 length;    __u32 blob_id;};

Members

data

Pointer to data to copy.

length

Length of data to copy.

blob_id

Return: new property ID.

Description

Create a new ‘blob’ data property, copying length bytes from data pointer,and returning new blob ID.

structdrm_mode_destroy_blob

Destroy user blob

Definition:

struct drm_mode_destroy_blob {    __u32 blob_id;};

Members

blob_id

blob_id to destroy

Description

Destroy a user-created blob property.

User-space can release blobs as soon as they do not need to refer to them bytheir blob object ID. For instance, if you are using a MODE_ID blob in anatomic commit and you will not make another commit re-using the same ID, youcan destroy the blob as soon as the commit has been issued, without waitingfor it to complete.

structdrm_mode_create_lease

Create lease

Definition:

struct drm_mode_create_lease {    __u64 object_ids;    __u32 object_count;    __u32 flags;    __u32 lessee_id;    __u32 fd;};

Members

object_ids

Pointer to array of object ids (__u32)

object_count

Number of object ids

flags

flags for new FD (O_CLOEXEC, etc)

lessee_id

Return: unique identifier for lessee.

fd

Return: file descriptor to new drm_master file

Description

Lease mode resources, creating another drm_master.

Theobject_ids array must reference at least one CRTC, one connector andone plane ifDRM_CLIENT_CAP_UNIVERSAL_PLANES is enabled. Alternatively,the lease can be completely empty.

structdrm_mode_list_lessees

List lessees

Definition:

struct drm_mode_list_lessees {    __u32 count_lessees;    __u32 pad;    __u64 lessees_ptr;};

Members

count_lessees

Number of lessees.

On input, provides length of the array.On output, provides total number. Nomore than the input number will be writtenback, so two calls can be used to getthe size and then the data.

pad

Padding.

lessees_ptr

Pointer to lessees.

Pointer to __u64 array of lessee ids

Description

List lesses from a drm_master.

structdrm_mode_get_lease

Get Lease

Definition:

struct drm_mode_get_lease {    __u32 count_objects;    __u32 pad;    __u64 objects_ptr;};

Members

count_objects

Number of leased objects.

On input, provides length of the array.On output, provides total number. Nomore than the input number will be writtenback, so two calls can be used to getthe size and then the data.

pad

Padding.

objects_ptr

Pointer to objects.

Pointer to __u32 array of object ids.

Description

Get leased objects.

structdrm_mode_revoke_lease

Revoke lease

Definition:

struct drm_mode_revoke_lease {    __u32 lessee_id;};

Members

lessee_id

Unique ID of lessee

structdrm_mode_rect

Two dimensional rectangle.

Definition:

struct drm_mode_rect {    __s32 x1;    __s32 y1;    __s32 x2;    __s32 y2;};

Members

x1

Horizontal starting coordinate (inclusive).

y1

Vertical starting coordinate (inclusive).

x2

Horizontal ending coordinate (exclusive).

y2

Vertical ending coordinate (exclusive).

Description

With drm subsystem usingstructdrm_rect to manage rectangular area thisexport it to user-space.

Currently used by drm_mode_atomic blob property FB_DAMAGE_CLIPS.

structdrm_mode_closefb

Definition:

struct drm_mode_closefb {    __u32 fb_id;    __u32 pad;};

Members

fb_id

Framebuffer ID.

pad

Must be zero.

dma-buf interoperability

Please seeExchanging pixel buffers forinformation on how dma-buf is integrated and exposed within DRM.

Trace events

SeeUsing the Linux Kernel Tracepoints for information about usingLinux Kernel Tracepoints.In the DRM subsystem, some events are considered stable uAPI to avoidbreaking tools (e.g.: GPUVis, umr) relying on them. Stable means that fieldscannot be removed, nor their formatting updated. Adding new fields ispossible, under the normal uAPI requirements.

Stable uAPI events

Fromdrivers/gpu/drm/scheduler/gpu_scheduler_trace.h

drm_sched_job_queue,drm_sched_job_run,drm_sched_job_add_dep,drm_sched_job_done anddrm_sched_job_unschedulable are consideredstable uAPI.

Common trace events attributes:

All the events depends ondrm_sched_job_arm() having been called already forthe job because they usestructdrm_sched_job.sched orstructdrm_sched_job.s_fence.