Hubbry Logo
Direct Rendering ManagerDirect Rendering ManagerMain
Open search
Direct Rendering Manager
Community hub
Direct Rendering Manager
logo
7 pages, 0 posts
0 subscribers
Be the first to start a discussion here.
Be the first to start a discussion here.
Direct Rendering Manager
Direct Rendering Manager
from Wikipedia
Original authorskernel.org & freedesktop.org
Developerskernel.org & freedesktop.org
Written inC
Type
License
Websitedri.freedesktop.org/wiki/DRM

The Direct Rendering Manager (DRM) is a subsystem of the Linux kernel responsible for interfacing with GPUs of modern video cards. DRM exposes an API that user-space programs can use to send commands and data to the GPU and perform operations such as configuring the mode setting of the display. DRM was first developed as the kernel-space component of the X Server Direct Rendering Infrastructure,[1] but since then it has been used by other graphic stack alternatives such as Wayland and standalone applications and libraries such as SDL2 and Kodi.

User-space programs can use the DRM API to command the GPU to do hardware-accelerated 3D rendering and video decoding, as well as GPGPU computing.

Overview

[edit]

The Linux kernel already had an API called fbdev, used to manage the framebuffer of a graphics adapter,[2] but it couldn't be used to handle the needs of modern 3D-accelerated GPU-based video hardware. These devices usually require setting and managing a command queue in their own memory to dispatch commands to the GPU and also require management of buffers and free space within that memory.[3] Initially, user-space programs (such as the X Server) directly managed these resources, but they usually acted as if they were the only ones with access to them. When two or more programs tried to control the same hardware at the same time, and set its resources each one in its own way, most times they ended catastrophically.[3]

Access to video card without DRM
Without DRM
Access to video card with DRM
With DRM
DRM allows multiple programs concurrent access to the 3D video card, avoiding collisions.

The Direct Rendering Manager was created to allow multiple programs to use video hardware resources cooperatively.[4] The DRM gets exclusive access to the GPU and is responsible for initializing and maintaining the command queue, memory, and any other hardware resource. Programs wishing to use the GPU send requests to DRM, which acts as an arbitrator and takes care to avoid possible conflicts.

The scope of DRM has been expanded over the years to cover more functionality previously handled by user-space programs, such as framebuffer managing and mode setting, memory-sharing objects and memory synchronization.[5][6] Some of these expansions were given specific names, such as Graphics Execution Manager (GEM) or kernel mode-setting (KMS), and the terminology prevails when the functionality they provide is specifically alluded. But they are really parts of the whole kernel DRM subsystem.

The trend to include two GPUs in a computer—a discrete GPU and an integrated one—led to new problems such as GPU switching that also needed to be solved at the DRM layer. In order to match the Nvidia Optimus technology, DRM was provided with GPU offloading abilities, called PRIME.[7]

Software architecture

[edit]
A process using the Direct Rendering Manager of the Linux Kernel to access a 3D accelerated graphics card

The Direct Rendering Manager resides in kernel space, so user-space programs must use kernel system calls to request its services. However, DRM doesn't define its own customized system calls. Instead, it follows the Unix principle of "everything is a file" to expose the GPUs through the filesystem name space, using device files under the /dev hierarchy. Each GPU detected by DRM is referred to as a DRM device, and a device file /dev/dri/cardX (where X is a sequential number) is created to interface with it.[8][9] User-space programs that want to talk to the GPU must open this file and use ioctl calls to communicate with DRM. Different ioctls correspond to different functions of the DRM API.

A library called libdrm was created to facilitate the interface of user-space programs with the DRM subsystem. This library is merely a wrapper that provides a function written in C for every ioctl of the DRM API, as well as constants, structures and other helper elements.[10] The use of libdrm not only avoids exposing the kernel interface directly to applications, but presents the usual advantages of reusing and sharing code between programs.

Direct Rendering Manager architecture details: DRM core and DRM driver (including GEM and KMS) interfaced by libdrm

DRM consists of two parts: a generic "DRM core" and a specific one ("DRM driver") for each type of supported hardware.[11] DRM core provides the basic framework where different DRM drivers can register and also provides to user space a minimal set of ioctls with common, hardware-independent functionality.[8] A DRM driver, on the other hand, implements the hardware-dependent part of the API, specific to the type of GPU it supports; it should provide the implementation of the remaining ioctls not covered by DRM core, but it may also extend the API, offering additional ioctls with extra functionality only available on such hardware.[8] When a specific DRM driver provides an enhanced API, user-space libdrm is also extended by an extra library libdrm-driver that can be used by user space to interface with the additional ioctls.

API

[edit]

The DRM core exports several interfaces to user-space applications, generally intended to be used through corresponding libdrm wrapper functions. In addition, drivers export device-specific interfaces for use by user-space drivers and device-aware applications through ioctls and sysfs files. External interfaces include: memory mapping, context management, DMA operations, AGP management, vblank control, fence management, memory management, and output management.

DRM-Master and DRM-Auth

[edit]

There are several operations (ioctls) in the DRM API that either for security purposes or for concurrency issues must be restricted to be used by a single user-space process per device.[8] To implement this restriction, DRM limits such ioctls to be only invoked by the process considered the "master" of a DRM device, usually called DRM-Master. Only one of all processes that have the device node /dev/dri/cardX opened will have its file handle marked as master, specifically the first calling the SET_MASTER ioctl. Any attempt to use one of these restricted ioctls without being the DRM-Master will return an error. A process can also give up its master role—and let another process acquire it—by calling the DROP_MASTER ioctl.

The X Server—or any other display server—is commonly the process that acquires the DRM-Master status in every DRM device it manages, usually when it opens the corresponding device node during its startup, and keeps these privileges for the entire graphical session until it finishes or dies.

For the remaining user-space processes there is another way to gain the privilege to invoke some restricted operations on the DRM device called DRM-Auth. It is basically a method of authentication against the DRM device, in order to prove to it that the process has the DRM-Master's approval to get such privileges. The procedure consists of:[12]: 13 

  • The client gets a unique token—a 32-bit integer—from the DRM device using the GET_MAGIC ioctl and passes it to the DRM-Master process by whatever means (normally some sort of IPC; for example, in DRI2 there is a DRI2Authenticate request that any X client can send to the X Server.[13])
  • The DRM-Master process, in turn, sends back the token to the DRM device by invoking the AUTH_MAGIC ioctl.
  • The device grants special rights to the process file handle whose auth token matches the received token from the DRM-Master.

Graphics Execution Manager

[edit]

Due to the increasing size of video memory and the growing complexity of graphics APIs such as OpenGL, the strategy of reinitializing the graphics card state at each context switch was too expensive, performance-wise. Also, modern Linux desktops needed an optimal way to share off-screen buffers with the compositing manager. These requirements led to the development of new methods to manage graphics buffers inside the kernel. The Graphics Execution Manager (GEM) emerged as one of these methods.[6]

GEM provides an API with explicit memory management primitives.[6] Through GEM, a user-space program can create, handle and destroy memory objects living in the GPU video memory. These objects, called "GEM objects",[14] are persistent from the user-space program's perspective and don't need to be reloaded every time the program regains control of the GPU. When a user-space program needs a chunk of video memory (to store a framebuffer, texture or any other data required by the GPU[15]), it requests the allocation to the DRM driver using the GEM API. The DRM driver keeps track of the used video memory and is able to comply with the request if there is free memory available, returning a "handle" to user space to further refer the allocated memory in coming operations.[6][14] GEM API also provides operations to populate the buffer and to release it when it is not needed anymore. Memory from unreleased GEM handles gets recovered when the user-space process closes the DRM device file descriptor—intentionally or because it terminates.[16]

GEM also allows two or more user-space processes using the same DRM device (hence the same DRM driver) to share a GEM object.[16] GEM handles are local 32-bit integers unique to a process but repeatable in other processes, therefore not suitable for sharing. What is needed is a global namespace, and GEM provides one through the use of global handles called GEM names. A GEM name refers to one, and only one, GEM object created within the same DRM device by the same DRM driver, by using a unique 32-bit integer. GEM provides an operation flink to obtain a GEM name from a GEM handle.[16][12]: 16  The process can then pass this GEM name (32-bit integer) to another process using any IPC mechanism available.[12]: 15  The GEM name can be used by the recipient process to obtain a local GEM handle pointing to the original GEM object.

Unfortunately, the use of GEM names to share buffers is not secure.[12]: 16 [17][18] A malicious third-party process accessing the same DRM device could try to guess the GEM name of a buffer shared by two other processes, simply by probing 32-bit integers.[19][18] Once a GEM name is found, its contents can be accessed and modified, violating the confidentiality and integrity of the information of the buffer. This drawback was overcome later by the introduction of DMA-BUF support into DRM, as DMA-BUF represents buffers in userspace as file descriptors, which may be shared securely.

Another important task for any video-memory management system besides managing the video-memory space is handling the memory synchronization between the GPU and the CPU. Current memory architectures are very complex and usually involve various levels of caches for the system memory and sometimes for the video memory too. Therefore, video-memory managers should also handle the cache coherence to ensure the data shared between CPU and GPU is consistent.[20] This means that often video-memory management internals are highly dependent on hardware details of the GPU and memory architecture, and thus driver-specific.[21]

GEM was initially developed by Intel engineers to provide a video-memory manager for its i915 driver.[20] The Intel GMA 9xx family are integrated GPUs with a Uniform Memory Architecture (UMA), where the GPU and CPU share the physical memory, and there is not a dedicated VRAM.[22] GEM defines "memory domains" for memory synchronization, and while these memory domains are GPU-independent,[6] they are specifically designed with an UMA memory architecture in mind, making them less suitable for other memory architectures like those with a separate VRAM. For this reason, other DRM drivers have decided to expose to user-space programs the GEM API, but internally they implemented a different memory manager better suited for their particular hardware and memory architecture.[23]

The GEM API also provides ioctls for control of the execution flow (command buffers), but they are Intel-specific, to be used with Intel i915 and later GPUs.[6] No other DRM driver has attempted to implement any part of the GEM API beyond the memory-management specific ioctls.

Translation Table Maps

[edit]

Translation Table Maps (TTM) is the name of the generic memory manager for GPUs that was developed before GEM.[5][14] It was specifically designed to manage the different types of memory that a GPU might access, including dedicated Video RAM (commonly installed in the video card) and system memory accessible through an I/O memory management unit called the Graphics Address Remapping Table (GART).[5] TTM should also handle the portions of the video RAM that are not directly addressable by the CPU and do it with the best possible performance, considering that user-space graphics applications typically work with large amounts of video data. Another important matter was to maintain the consistency between the different memories and caches involved.

The main concept of TTM are the "buffer objects", regions of video memory that at some point must be addressable by the GPU.[5] When a user-space graphics application wants access to a certain buffer object (usually to fill it with content), TTM may require relocating it to a type of memory addressable by the CPU. Further relocations—or GART mapping operations—could happen when the GPU needs access to a buffer object but it isn't in the GPU's address space yet. Each of these relocation operations must handle any related data and cache-coherency issues.[5]

Another important TTM concept is fences. Fences are essentially a mechanism to manage concurrency between the CPU and the GPU.[24] A fence tracks when a buffer object is no longer used by the GPU, generally to notify any user-space process with access to it.[5]

The fact that TTM tried to manage all kind of memory architectures, including those with and without a dedicated VRAM, in a suitable way, and to provide every conceivable feature in a memory manager for use with any type of hardware, led to an overly complex solution with an API far larger than needed.[24][14] Some DRM developers thought that it wouldn't fit well with any specific driver, especially the API. When GEM emerged as a simpler memory manager, its API was preferred over the TTM one. But some driver developers considered that the approach taken by TTM was more suitable for discrete video cards with dedicated video memory and IOMMUs, so they decided to use TTM internally, while exposing their buffer objects as GEM objects and thus supporting the GEM API.[23] Examples of current drivers using TTM as an internal memory manager but providing a GEM API are the radeon driver for AMD video cards and the nouveau driver for NVIDIA video cards.

DMA Buffer Sharing and PRIME

[edit]

The DMA Buffer Sharing API (often abbreviated as DMA-BUF) is a Linux kernel internal API designed to provide a generic mechanism to share DMA buffers across multiple devices, possibly managed by different types of device drivers.[25][26] For example, a Video4Linux device and a graphics adapter device could share buffers through DMA-BUF to achieve zero-copy of the data of a video stream produced by the first and consumed by the latter. Any Linux device driver can implement this API as exporter, as user (consumer) or both.

This feature was exploited for the first time in DRM to implement PRIME, a solution for GPU offloading that uses DMA-BUF to share the resulting framebuffers between the DRM drivers of the discrete and the integrated GPU.[27]: 13  An important feature of DMA-BUF is that a shared buffer is presented to user space as a file descriptor.[14][12]: 17  For the development of PRIME two new ioctls were added to the DRM API, one to convert a local GEM handle to a DMA-BUF file descriptor and another for the exact opposite operation.

These two new ioctls were later reused as a way to fix the inherent unsafety of GEM buffer sharing.[12]: 17  Unlike GEM names, file descriptors can not be guessed (they are not a global namespace), and Unix operating systems provide a safe way to pass them through a Unix domain socket using the SCM_RIGHTS semantics.[14][28]: 11  A process that wants to share a GEM object with another process can convert its local GEM handle to a DMA-BUF file descriptor and pass it to the recipient, which in turn can get its own GEM handle from the received file descriptor.[12]: 16  This method is used by DRI3 to share buffers between the client and the X Server[29] and also by Wayland.

Kernel Mode Setting

[edit]
There must be a "DRM master" in user-space, this program has exclusive access to KMS.

In order to work properly, a video card or graphics adapter must set a mode—a combination of screen resolution, color depth and refresh rate—that is within the range of values supported by itself and the attached display screen. This operation is called mode-setting,[30] and it usually requires raw access to the graphics hardware—i.e. the ability to write to certain registers of the video card display controller.[31][32] A mode-setting operation must be performed before starting to use the framebuffer, and also when the mode is required to change by an application or the user.

In the early days, user-space programs that wanted to use the graphical framebuffer were also responsible for providing the mode-setting operations.[3] Thus, they needed to run with privileged access to the video hardware. In Unix-type operating systems, the X Server was the most prominent example. Its mode-setting implementation lived in the DDX driver for each specific type of video card.[33] This approach, later referred to as User space Mode-Setting or UMS,[34][35] poses several issues.[36][30] It not only breaks the isolation that operating systems should provide between programs and hardware, raising both stability and security concerns, but also could leave the graphics hardware in an inconsistent state if two or more user space programs try to do the mode-setting at the same time. To avoid these conflicts, the X Server became in practice the only user space program that performed mode-setting operations; the remainder user space programs relied on the X Server to set the appropriate mode and to handle any other operation involving mode-setting. Initially the mode-setting was performed exclusively during the X Server startup process, but later the X Server gained the ability to do it while running.[37] The XFree86-VidModeExtension extension was introduced in XFree86 3.1.2 to let any X client request modeline (resolution) changes to the X Server.[38][39] VidMode extension was later superseded by the more generic XRandR extension.

However, this was not the only code doing mode-setting in a Linux system. During the system booting process, the Linux kernel must set a minimal text mode for the virtual console (based on the standard modes defined by VESA BIOS extensions).[40] Also the Linux kernel framebuffer driver contained mode-setting code to configure framebuffer devices.[2] To avoid mode-setting conflicts, the XFree86 Server—and later the X.Org Server—handled the case when the user switched from the graphical environment to a text virtual console by saving its mode-setting state, and restoring it when the user switched back to X.[41] This process caused an annoying flicker in the transition, and also can fail, leading to a corrupted or unusable output display.[42]

The user space mode setting approach also caused other issues:[43][42]

  • The suspend/resume process has to rely on user space tools to restore the previous mode. One single failure or crash of one of these programs could leave the system without a working display due to a modeset misconfiguration, and therefore unusable.
  • It was also impossible for the kernel to show error or debug messages when the screen was in a graphics mode—for example when X was running—since the only modes the kernel knew about were the VESA BIOS standard text modes.
  • A more pressing issue was the proliferation of graphical applications bypassing the X Server and the emergence of other graphics stack alternatives to X, extending the duplication of mode-setting code across the system even further.

To address these problems, the mode-setting code was moved to a single place inside the kernel, specifically to the existing DRM module.[36][37][44][42][43] Then, every process—including the X Server—should be able to command the kernel to perform mode-setting operations, and the kernel would ensure that concurrent operations don't result in an inconsistent state. The new kernel API and code added to the DRM module to perform these mode-setting operations was called Kernel Mode-Setting (KMS).[30]

Kernel Mode-Setting provides several benefits. The most immediate is of course the removal of duplicate mode-setting code, from both the kernel (Linux console, fbdev) and user space (X Server DDX drivers). KMS also makes it easier to write alternative graphics systems, which now don't need to implement their own mode-setting code.[42][43] By providing centralized mode management, KMS solves the flickering issues while changing between console and X, and also between different instances of X (fast user switching).[41][44] Since it is available in the kernel, it can also be used at the beginning of the boot process, saving flickering due to mode changes in these early stages.

The fact that KMS is part of the kernel allows it to use resources only available at kernel space such as interrupts.[45] For example, the mode recovery after a suspend/resume process simplifies a lot by being managed by the kernel itself, and incidentally improves security (no more user space tools requiring root permissions). The kernel also allows the hotplug of new display devices easily, solving a longstanding problem.[45] Mode-setting is also closely related to memory management—since framebuffers are basically memory buffers—so a tight integration with the graphics memory manager is highly recommended. That's the main reason why the kernel mode-setting code was incorporated into DRM and not as a separate subsystem.[44]

To avoid breaking backwards compatibility of the DRM API, Kernel Mode-Setting is provided as an additional driver feature of certain DRM drivers.[46] Any DRM driver can choose to provide the DRIVER_MODESET flag when it registers with the DRM core to indicate that supports the KMS API.[8] Those drivers that implement Kernel Mode-Setting are often called KMS drivers as a way to differentiate them from the legacy—without KMS—DRM drivers.

KMS has been adopted to such an extent that certain drivers which lack 3D acceleration (or for which the hardware vendor doesn't want to expose or implement it) nevertheless implement the KMS API without the rest of the DRM API, allowing display servers (like Wayland) to run with ease.[47][48]

KMS device model

[edit]

KMS models and manages the output devices as a series of abstract hardware blocks commonly found on the display output pipeline of a display controller. These blocks are:[49]

  • CRTCs: each CRTC (from CRT Controller[50][33]) represents a scanout engine of the display controller, pointing to a scanout buffer (framebuffer).[49] The purpose of a CRTC is to read the pixel data currently in the scanout buffer and generate from it the video mode timing signal with the help of a PLL circuit.[51] The number of CRTCs available determines how many independent output devices the hardware can handle at the same time, so in order to use multi-head configurations at least one CRTC per display device is required.[49] Two—or more—CRTCs can also work in clone mode if they scan out from the same framebuffer to send the same image to several output devices.[51][50]
  • Connectors: a connector represents where the display controller sends the video signal from a scanout operation to be displayed. Usually, the KMS concept of a connector corresponds to a physical connector (VGA, DVI, FPD-Link, HDMI, DisplayPort, S-Video, ...) in the hardware where an output device (monitor, laptop panel, ...) is permanently or can temporarily be attached. Information related to the current physically attached output device—such as connection status, EDID data, DPMS status or supported video modes—is also stored within the connector.[49]
  • Encoders: the display controller must encode the video mode timing signal from the CRTC using a format suitable for the intended connector.[49] An encoder represents the hardware block able to do one of these encodings. Examples of encodings—for digital outputs—are TMDS and LVDS; for analog outputs such as VGA and TV out, specific DAC blocks are generally used. A connector can only receive the signal from one encoder at a time,[49] and each type of connector only supports some encodings. There also might be additional physical restrictions by which not every CRTC is connected to every available encoder, limiting the possible combinations of CRTC-encoder-connector.
  • Planes: a plane is not a hardware block but a memory object containing a buffer from which a scanout engine (a CRTC) is fed. The plane that holds the framebuffer is called the primary plane, and each CRTC must have one associated,[49] since it is the source for the CRTC to determine the video mode—display resolution (width and height), pixel size, pixel format, refresh rate, etc. A CRTC might have also cursor planes associated to it if the display controller supports hardware cursor overlays, or secondary planes if it's able to scan out from additional hardware overlays and compose or blend "on the fly" the final image sent to the output device.[33]

Atomic Display

[edit]

In recent years there has been an ongoing effort to bring atomicity to some regular operations pertaining the KMS API, specifically to the mode setting and page flipping operations.[33][52] This enhanced KMS API is what is called Atomic Display (formerly known as atomic mode-setting and atomic or nuclear pageflip).

The purpose of the atomic mode-setting is to ensure a correct change of mode in complex configurations with multiple restrictions, by avoiding intermediate steps which could lead to an inconsistent or invalid video state;[52] it also avoids risky video states when a failed mode-setting process has to be undone ("rollback").[53]: 9  Atomic mode-setting allows one to know beforehand if certain specific mode configuration is appropriate, by providing mode testing capabilities.[52] When an atomic mode is tested and its validity confirmed, it can be applied with a single indivisible (atomic) commit operation. Both test and commit operations are provided by the same new ioctl with different flags.

Atomic page flip on the other hand allows to update multiple planes on the same output (for instance the primary plane, the cursor plane and maybe some overlays or secondary planes) all synchronized within the same VBLANK interval, ensuring a proper display without tearing.[53]: 9,14 [52] This requirement is especially relevant to mobile and embedded display controllers, that tend to use multiple planes/overlays to save power.

The new atomic API is built upon the old KMS API. It uses the same model and objects (CRTCs, encoders, connectors, planes, ...), but with an increasing number of object properties that can be modified.[52] The atomic procedure is based on changing the relevant properties to build the state that we want to test or commit. The properties we want to modify depend on whether we want to do a mode-setting (mostly CRTCs, encoders and connectors properties) or page flipping (usually planes properties). The ioctl is the same for both cases, the difference being the list of properties passed with each one.[54]

Render nodes

[edit]

In the original DRM API, the DRM device /dev/dri/cardX is used for both privileged (modesetting, other display control) and non-privileged (rendering, GPGPU compute) operations.[9] For security reasons, opening the associated DRM device file requires special privileges "equivalent to root-privileges".[55] This leads to an architecture where only some reliable user space programs (the X server, a graphical compositor, ...) have full access to the DRM API, including the privileged parts like the modeset API. Other user space applications that want to render or make GPGPU computations should be granted by the owner of the DRM device ("DRM Master") through the use of a special authentication interface.[56] Then the authenticated applications can render or make computations using a restricted version of the DRM API without privileged operations. This design imposes a severe constraint: there must always be a running graphics server (the X Server, a Wayland compositor, ...) acting as DRM-Master of a DRM device so that other user space programs can be granted the use of the device, even in cases not involving any graphics display like GPGPU computations.[55][56]

The "render nodes" concept tries to solve these scenarios by splitting the DRM user space API into two interfaces – one privileged and one non-privileged – and using separate device files (or "nodes") for each one.[9] For every GPU found, its corresponding DRM driver—if it supports the render nodes feature—creates a device file /dev/dri/renderDX, called the render node, in addition to the primary node /dev/dri/cardX.[56][9] Clients that use a direct rendering model and applications that want to take advantage of the computing facilities of a GPU, can do it without requiring additional privileges by simply opening any existing render node and dispatching GPU operations using the limited subset of the DRM API supported by those nodes—provided they have file system permissions to open the device file. Display servers, compositors and any other program that requires the modeset API or any other privileged operation must open the standard primary node that grants access to the full DRM API and use it as usual. Render nodes explicitly disallow the GEM flink operation to prevent buffer sharing using insecure GEM global names; only PRIME (DMA-BUF) file descriptors can be used to share buffers with another client, including the graphics server.[9][56]

Hardware support

[edit]
DRM is to be used by user-mode graphics devices driver, like e.g. AMD Catalyst or Mesa 3D. User-space programs use the Linux System Call Interface to access DRM. DRM augments the Linux System Call Interface with own system calls.[57]

The Linux DRM subsystem includes free and open-source drivers to support hardware from the 3 main manufacturers of GPUs for desktop computers (AMD, NVIDIA and Intel), as well as from a growing number of mobile GPU and System on a chip (SoC) integrators. The quality of each driver varies highly, depending on the degree of cooperation by the manufacturer and other matters.

DRM drivers
Driver Since kernel Supported hardware Vendor support Status/Notes
radeon 2.4.1 AMD (formerly ATi) Radeon GPU series with the architectures TeraScale and GCN 1st & 2nd gen. Including models from R100/200/300/400, Radeon X1000, HD 2000/3000/4000/5000/6000/7000/8000, R5/R7/R9 200/300 series and Kaveri APUs. Yes Active
i915 2.6.9 Intel GMA 830M, 845G, 852GM, 855GM, 865G, 915G, 945G, 965G, G35, G41, G43, G45 chipsets. Intel HD and Iris Graphics HD Graphics 2000/3000/2500/4000/4200/4400/4600/P4600/P4700/5000, Iris Graphics 5100, Iris Pro Graphics 5200 integrated GPUs. Yes Active
nouveau 2.6.33[58][59] NVIDIA Tesla, Fermi, Kepler, Maxwell based GeForce GPUs, Tegra K1, X1 SoC Partial Active
exynos 3.2[60] Samsung ARM-based Exynos SoCs
vmwgfx 3.2 (from staging)[61] Virtual GPU for the VMware SVGA2 virtual driver
gma500 3.3 (from staging)[62][63] Intel GMA 500 and other Imagination Technologies (PowerVR) based graphics GPUs experimental 2D KMS-only driver
ast 3.5[64] ASpeed Technologies 2000 series experimental
mgag200 3.5[65] Matrox MGA-G200 server display engines KMS-only
shmobile 3.7[66] Renesas SH Mobile
tegra 3.8[67] Nvidia Tegra20, Tegra30 SoCs Yes Active
omapdrm 3.9[68] Texas Instruments OMAP5 SoCs
rcar-du 3.11[69] Renesas R-Car SoC Display Units
msm 3.12[70][71] Qualcomm's Adreno A2xx/A3xx/A4xx GPU families (Snapdragon SOCs)[72]
armada 3.13[73][74] Marvell Armada 510 SoCs
bochs 3.14[75] Virtual VGA cards using the Bochs dispi vga interface (such as QEMU stdvga) virtual driver
sti 3.17[76][77] STMicroelectronics SoC stiH41x series
imx 3.19 (from staging)[78][79] Freescale i.MX SoCs
rockchip 3.19[78][80] Rockchip SoC-based GPUs KMS-only
amdgpu[57] 4.2[81][82] AMD Radeon GPU series with the architectures GCN 3rd & 4th gen. Including models from Radeon Rx 200/300/400/500[83] series and Carrizo and Bristol & Stoney Ridge APUs. Yes Active
virtio 4.2[84] Virtual GPU driver for QEMU based virtual machine managers (like KVM or Xen) virtual driver
vc4 4.4[85][86][87] Raspberry Pi's Broadcom BCM2835 and BCM2836 SoCs (VideoCore IV GPU)
etnaviv 4.5[88][89][90] Vivante GPU cores found in several SoCs such as Marvell ARMADA and Freescale i.MX6 Series
sun4i 4.7[91][92] Allwinner SoCs (ARM Mali-400 GPU)
kirin 4.7[93][92] HiSilicon Kirin hi6220 SoC (ARM Mali 450-MP4 GPU)
mediatek 4.7[94][92] MediaTek MT8173 SoC (Imagination PowerVR GX6250 GPU)
hibmc 4.10[95] HiSilicon hi1710 Huawei iBMC SoC (Silicon Image SM750 GPU core[96]) KMS-only
vkms 4.19[97][98] Software-only model of a KMS driver that is useful for testing and for running X (or similar) on headless machines. virtual driver, experimental
lima 5.2[99][100] ARM Mali 4xx GPUs
panfrost 5.2[101][100] ARM Mali Txxx (Midgard) and Gxx (Bifrost) GPUs
vboxvideo 5.2 (from staging)[102][100] Virtual GPU driver for VirtualBox (VBoxVGA GPU) virtual driver
hyperv_drm 5.14[103][104] Virtual GPU driver for Hyper-V synthetic video device virtual driver
simpledrm 5.14[105][106] GPU Driver for firmware-provided framebuffers (UEFI GOP, VESA BIOS Extensions, embedded systems) KMS-only
ofdrm 6.2[107][108] GPU Driver for Open Firmware framebuffers KMS-only
loongson 6.6[109][110] GPU Driver for Loongson GPUs and SoCs
powervr 6.8[111][112] Imagination Technologies PowerVR (Series 6 and later) & IMG Graphics GPUs
xe 6.8[113][114] Intel Xe series GPUs (Gen12 integrated GPUs, Intel Arc discrete GPUs) Yes experimental
panthor 6.10[115][116] ARM Mali Gxxx (Valhall) GPUs
efidrm 6.16[117][118] GPU Driver for EFI framebuffers (UEFI GOP) KMS-only
vesadrm 6.16[119][118] GPU Driver for VESA framebuffers (VESA BIOS Extensions) KMS-only

There is also a number of drivers for old, obsolete hardware detailed in the next table for historical purposes.

Historic DRM drivers
Driver Since kernel Supported hardware Status/Notes
gamma 2.3.18 3Dlabs GLINT GMX 2000 Removed since 2.6.14[120]
ffb 2.4 Creator/Creator3D (used by Sun Microsystems Ultra workstations) Removed since 2.6.21[121]
tdfx 2.4 3dfx Banshee/Voodoo3+ Removed since 6.3[122]
mga 2.4 Matrox G200/G400/G450 Removed since 6.3[123]
r128 2.4 ATI Rage 128 Removed since 6.3[124]
i810 2.4 Intel i810 Removed since 6.3[125]
sis 2.4.17 SiS 300/630/540 Removed since 6.3[126]
i830 2.4.20 Intel 830M/845G/852GM/855GM/865G Removed since 2.6.39[127] (replaced by i915 driver)
via 2.6.13[128] VIA Unichrome / Unichrome Pro Removed since 6.3[129]
savage 2.6.14[130] S3 Graphics Savage 3D/MX/IX/4/SuperSavage/Pro/Twister Removed since 6.3[131]

Development

[edit]

The Direct Rendering Manager is developed within the Linux kernel, and its source code resides in the /drivers/gpu/drm directory of the Linux source code. The subsystem maintainer is Dave Airlie, with other maintainers taking care of specific drivers.[132] As usual in the Linux kernel development, DRM submaintainers and contributors send their patches with new features and bug fixes to the main DRM maintainer which integrates them into its own Linux repository. The DRM maintainer in turn submits all of these patches that are ready to be mainlined to Linus Torvalds whenever a new Linux version is going to be released. Torvalds, as top maintainer of the whole kernel, holds the last word on whether a patch is suitable or not for inclusion in the kernel.

For historical reasons, the source code of the libdrm library is maintained under the umbrella of the Mesa project.[133]

History

[edit]

In 1999, while developing DRI for XFree86, Precision Insight created the first version of DRM for the 3dfx video cards, as a Linux kernel patch included within the Mesa source code.[134] Later that year, the DRM code was mainlined in Linux kernel 2.3.18 under the /drivers/char/drm/ directory for character devices.[135] During the following years the number of supported video cards grew. When Linux 2.4.0 was released in January 2001 there was already support for Creative Labs GMX 2000, Intel i810, Matrox G200/G400 and ATI Rage 128, in addition to 3dfx Voodoo3 cards,[136] and that list expanded during the 2.4.x series, with drivers for ATI Radeon cards, some SiS video cards and Intel 830M and subsequent integrated GPUs.

The split of DRM into two components, DRM core and DRM driver, called DRM core/personality split was done during the second half of 2004,[11][137] and merged into kernel version 2.6.11.[138] This split allowed multiple DRM drivers for multiple devices to work simultaneously, opening the way to multi-GPU support.

The idea of putting all the video mode setting code in one place inside the kernel had been acknowledged for years,[139][140] but the graphics card manufacturers had argued that the only way to do the mode-setting was to use the routines provided by themselves and contained in the Video BIOS of each graphics card. Such code had to be executed using x86 real mode, which prevented it from being invoked by a kernel running in protected mode.[44] The situation changed when Luc Verhaegen and other developers found a way to do the mode-setting natively instead of BIOS-based,[141][44] showing that it was possible to do it using normal kernel code and laying the groundwork for what would become Kernel Mode Setting. In May 2007 Jesse Barnes (Intel) published the first proposal for a drm-modesetting API and a working native implementation of mode-setting for Intel GPUs within the i915 DRM driver.[42] In December 2007 Jerome Glisse started to add the native mode-setting code for ATI cards to the radeon DRM driver.[142][143] Work on both the API and drivers continued during 2008, but got delayed by the necessity of a memory manager also in kernel space to handle the framebuffers.[144]

In October 2008 the Linux kernel 2.6.27 brought a major source code reorganization, prior to some significant upcoming changes. The DRM source code tree was moved to its own source directory /drivers/gpu/drm/ and the different drivers were moved into their own subdirectories. Headers were also moved into a new /include/drm directory.[145]

The increasing complexity of video memory management led to several approaches to solving this issue. The first attempt was the Translation Table Maps (TTM) memory manager, developed by Thomas Hellstrom (Tungsten Graphics) in collaboration with Emma Anholt (Intel) and Dave Airlie (Red Hat).[5] TTM was proposed for inclusion into mainline kernel 2.6.25 in November 2007,[5] and again in May 2008, but was ditched in favor of a new approach called Graphics Execution Manager (GEM).[24] GEM was first developed by Keith Packard and Emma Anholt from Intel as a simpler solution for memory management for their i915 driver.[6] GEM was well received and merged into the Linux kernel version 2.6.28 released in December 2008.[146] Meanwhile, TTM had to wait until September 2009 to be finally merged into Linux 2.6.31 as a requirement of the new Radeon KMS DRM driver.[147]

With memory management in place to handle buffer objects, DRM developers could finally add to the kernel the already finished API and code to do mode setting. This expanded API is what is called Kernel Mode-setting (KMS) and the drivers which implement it are often referred to as KMS drivers. In March 2009, KMS was merged into the Linux kernel version 2.6.29,[30][148] along with KMS support for the i915 driver.[149] The KMS API has been exposed to user space programs since libdrm 2.4.3.[150] The userspace X.Org DDX driver for Intel graphics cards was also the first to use the new GEM and KMS APIs.[151] KMS support for the radeon DRM driver was added to Linux 2.6.31 release of September 2009.[152][153][154] The new radeon KMS driver used the TTM memory manager but exposed GEM-compatible interfaces and ioctls instead of TTM ones.[23]

Since 2006 the nouveau project had been developing a free software DRM driver for NVIDIA GPUs outside of the official Linux kernel. In 2010 the nouveau source code was merged into Linux 2.6.33 as an experimental driver.[58][59] At the time of merging, the driver had been already converted to KMS, and behind the GEM API it used TTM as its memory manager.[155]

The new KMS API—including the GEM API—was a big milestone in the development of DRM, but it didn't stop the API from being enhanced in the following years. KMS gained support for page flips in conjunction with asynchronous VBLANK notifications in Linux 2.6.33[156][157]—only for the i915 driver, radeon and nouveau added it later during Linux 2.6.38 release.[158] The new page flip interface was added to libdrm 2.4.17.[159] In early 2011, during the Linux 2.6.39 release cycle, the so-called dumb buffers—a hardware-independent non-accelerated way to handle simple buffers suitable for use as framebuffers—were added to the KMS API.[160][161] The goal was to reduce the complexity of applications such as Plymouth that don't need to use special accelerated operations provided by driver-specific ioctls.[162] The feature was exposed by libdrm from version 2.4.25 onwards.[163] Later that year it also gained a new main type of objects, called planes. Planes were developed to represent hardware overlays supported by the scanout engine.[164][165] Plane support was merged into Linux 3.3.[166] and libdrm 2.4.30. Another concept added to the API—during Linux 3.5[167] and libdrm 2.4.36[168] releases—were generic object properties, a method to add generic values to any KMS object. Properties are specially useful to set special behaviour or features to objects such as CRTCs and planes.

An early proof of concept to provide GPU offloading between DRM drivers was developed by Dave Airlie in 2010.[7][169] Since Airlie was trying to mimic the NVIDIA Optimus technology, he decided to name it "PRIME".[7] Airlie resumed his work on PRIME in late 2011, but based on the new DMA-BUF buffer sharing mechanism introduced by Linux kernel 3.3.[170] The basic DMA-BUF PRIME infrastructure was finished in March 2012[171] and merged into the Linux 3.4 release,[172][173][174] as well as into libdrm 2.4.34.[175] Later during the Linux 3.5 release, several DRM drivers implemented PRIME support, including i915 for Intel cards, radeon for AMD cards and nouveau for NVIDIA cards.[176][177]

In recent years, the DRM API has incrementally expanded with new and improved features. In 2013, as part of GSoC, David Herrmann developed the multiple render nodes feature.[55] His code was added to the Linux kernel version 3.12 as an experimental feature[178][179] supported by i915,[180] radeon[181] and nouveau[182] drivers, and enabled by default since Linux 3.17.[77] In 2014 Matt Roper (Intel) developed the universal planes (or unified planes) concept by which framebuffers (primary planes), overlays (secondary planes) and cursors (cursor planes) are all treated as a single type of object with an unified API.[183] Universal planes support provides a more consistent DRM API with fewer, more generic ioctls.[33] In order to maintain the API backwards compatible, the feature is exposed by DRM core as an additional capability that a DRM driver can provide. Universal plane support debuted in Linux 3.15[184] and libdrm 2.4.55.[185] Several drivers, such as the Intel i915,[186] have already implemented it.

The most recent DRM API enhancement is the atomic mode-setting API, which brings atomicity to the mode-setting and page flipping operations on a DRM device. The idea of an atomic API for mode-setting was first proposed in early 2012.[187] Ville Syrjälä (Intel) took over the task of designing and implementing such atomic API.[188] Based on his work, Rob Clark (Texas Instruments) took a similar approach aiming to implement atomic page flips.[189] Later in 2013 both proposed features were reunited in a single one using a single ioctl for both tasks.[190] Since it was a requirement, the feature had to wait for the support of universal planes to be merged in mid-2014.[186] During the second half of 2014 the atomic code was greatly enhanced by Daniel Vetter (Intel) and other DRM developers[191]: 18  in order to facilitate the transition for the existing KMS drivers to the new atomic framework.[192] All of this work was finally merged into Linux 3.19[193] and Linux 4.0[194][195][196] releases, and enabled by default since Linux 4.2.[197] libdrm exposed the new atomic API since version 2.4.62.[198] Multiple drivers have already been converted to the new atomic API.[199] By 2018 ten new DRM drivers based on this new atomic model had been added to the Linux kernel.[200]

Adoption

[edit]

The Direct Rendering Manager kernel subsystem was initially developed to be used with the new Direct Rendering Infrastructure of the XFree86 4.0 display server, later inherited by its successor, the X.Org Server. Therefore, the main users of DRM were DRI clients that link to the hardware-accelerated OpenGL implementation that lives in the Mesa 3D library, as well as the X Server itself. Nowadays DRM is also used by several Wayland compositors, including Weston reference compositor. kmscon is a virtual console implementation that runs in user space using DRM KMS facilities.[201]

In 2015, version 358.09 (beta) of the proprietary Nvidia GeForce driver received support for the DRM mode-setting interface implemented as a new kernel blob called nvidia-modeset.ko. This new driver component works in conjunction with the nvidia.ko kernel module to program the display engine (i.e. display controller) of the GPU.[202]

See also

[edit]

References

[edit]
[edit]
Revisions and contributorsEdit on WikipediaRead on Wikipedia
from Grokipedia
The Direct Rendering Manager (DRM) is a subsystem of the that serves as a framework for managing graphics processing units (GPUs) and enabling direct hardware access for user-space applications, particularly for 3D acceleration and multimedia rendering. It provides a uniform interface to handle complex graphics devices with programmable pipelines, simplifying tasks such as memory allocation, interrupt processing, and (DMA) while enforcing security policies to prevent unauthorized . Developed as part of the broader (DRI) project initiated in 1999 by Precision Insight to support 3D graphics acceleration in for hardware like cards, DRM evolved from a character device driver into a comprehensive kernel module for . By providing mechanisms for synchronizing hardware access through per-device locks and a generic DMA engine capable of high-throughput buffer transfers (up to 10,000 dispatches per second at 40 MB/s over PCI), it allows multiple applications to share GPU resources securely without root privileges. Key components of DRM include Kernel Mode Setting (KMS), which handles display output configuration, mode setting, and vertical blanking synchronization to support modern setups; the Translation Table Maps (TTM) memory manager for unified buffer handling across different hardware architectures; and the Graphics Execution Manager (GEM) for simplified object-based memory allocation in user space. These elements work together via commands on DRM character devices (e.g., /dev/dri/card0), where hardware-specific drivers load upon GPU detection to authenticate clients and manage state changes under a single DRM master process. Over time, DRM has expanded to support a wide range of GPUs from vendors like , , and , integrating with libraries such as libdrm for application interfacing and facilitating advancements in open-source graphics stacks like Mesa. In the upcoming 6.18 (released December 2025), it incorporates new drivers, such as the "Rocket" accelerator for neural processing units (NPUs) on SoCs, underscoring its role in evolving graphics and compute capabilities.

Introduction

Overview

The Direct Rendering Manager (DRM) is a subsystem within the designed to manage access to graphics processing units (GPUs) and enable direct rendering capabilities without requiring CPU-mediated data transfers. It serves as the foundational kernel component for handling graphics hardware, providing a standardized framework for device initialization, resource allocation, and secure user-space access to GPU functionality. Originally developed to support accelerated 3D graphics, DRM has evolved into a comprehensive interface for both 2D and 3D rendering, video decoding, and display management across a wide range of hardware. At its core, DRM facilitates direct rendering by allowing user-space applications to submit rendering commands and data directly to the GPU hardware through kernel drivers, minimizing overhead and improving performance compared to traditional indirect rendering paths that involve server-side copying. Key functionalities include GPU memory allocation via managers like the Translation Table Maps (TTM) or Graphics Execution Manager (GEM), command submission through DMA engines, modesetting for display configuration, and mechanisms such as hardware locks and vblank event handling to coordinate access among multiple processes and prevent resource conflicts. These features support efficient handling of 2D/3D graphics workloads and , ensuring secure and concurrent hardware utilization. In the broader graphics ecosystem, DRM interacts with user-space libraries such as Mesa, which implements APIs like and , via the libdrm wrapper to expose kernel interfaces through device files like /dev/dri/card0. A high-level view of this interaction can be described as follows:

User-space Applications (e.g., Games, Browsers) | v Graphics Libraries (Mesa for [OpenGL](/page/OpenGL)/[Vulkan](/page/Vulkan)) | v libdrm (User-space [API](/page/API)) | v DRM Kernel Subsystem (Drivers for GPU) | v GPU Hardware

User-space Applications (e.g., Games, Browsers) | v Graphics Libraries (Mesa for [OpenGL](/page/OpenGL)/[Vulkan](/page/Vulkan)) | v libdrm (User-space [API](/page/API)) | v DRM Kernel Subsystem (Drivers for GPU) | v GPU Hardware

DRM has been integral to modern Linux distributions since kernel version 2.6, supporting GPUs from dozens of vendors including , , , and various embedded providers like Mali and Rockchip, thereby enabling widespread adoption in desktops, servers, and embedded systems.

Role in Linux Graphics Stack

The Direct Rendering Manager (DRM) serves as the primary kernel-level interface in the Linux graphics stack, bridging user-space components such as Mesa and Vulkan drivers with underlying graphics hardware to facilitate direct access and control. It provides a unified framework for managing graphics resources, including memory allocation and hardware synchronization, while enforcing security through mechanisms like device file permissions under /dev/dri. This architecture allows user-space applications to perform accelerated rendering without excessive kernel mediation, supporting modern graphics APIs and compositors like Wayland or X11. DRM relies on several key dependencies within the ecosystem to fulfill its role. It integrates with the subsystem to handle events such as hotplug detection for displays and input devices, ensuring seamless coordination between rendering and user interactions. For legacy fallbacks, DRM can leverage the framebuffer console interface when advanced mode setting is unavailable, providing a basic display pathway. Additionally, DRM works in tandem with the (DRI), which extends DRM's capabilities to user-space by enabling unprivileged programs to issue rendering commands directly to the GPU, thus supporting hardware-accelerated 3D without privileges. This integration is essential for the overall , where DRM manages the kernel-user space boundary to prevent unauthorized hardware access. In terms of operational flow, user-space applications interact with DRM primarily through calls on device files, initiating tasks like buffer allocation via objects for efficient memory handling, command queuing to submit GPU workloads, and page flip events to update display contents without tearing. is achieved using fences, which signal completion of rendering operations and coordinate multi-process access to shared resources, enabling concepts such as concurrent execution across multiple applications or virtual machines. This setup supports rendering by allowing buffers to be mapped directly between user-space and hardware, minimizing data transfers and optimizing performance for compute-intensive tasks. A distinctive aspect of DRM is its unification of render and display paths under a single framework, handling off-screen computations (rendering) through buffer objects and scanout operations (display) via mode setting, which eliminates the need for disparate legacy systems and streamlines resource sharing across the graphics stack.

History and Development

Origins and Evolution

The Direct Rendering Manager (DRM) originated in 1999 as a kernel subsystem developed under the project to enable direct hardware-accelerated on , bypassing the performance limitations of the existing device (fbdev) interface, which relied on CPU-intensive software emulation. Led by Precision Insight, Inc., with primary contributions from developer Rickard E. Faith, the initial DRM design provided secure, shared access to graphics hardware through a modular kernel framework, initially implemented as patches for video cards. The first mainline integration of DRM occurred with Linux kernel 2.4.0, released in January 2001, introducing support for Accelerated Graphics Port (AGP) memory bridging and basic command submission for rendering tasks. This addressed key bottlenecks in software rendering by allowing user-space applications to directly issue GPU commands via the Direct Rendering Infrastructure (DRI) version 1, which was fully integrated that year. Early drivers targeted hardware like the 3dfx Voodoo series for texture mapping acceleration and Matrox G200/G400 chips for vertex processing, marking the shift from monolithic fbdev handling to vendor-specific kernel modules. During the Linux 2.6 kernel series, starting with its release in December 2003, DRM evolved to incorporate advanced for efficient buffer allocation and sharing, as seen in the addition of a basic memory allocator in version 2.6.19. Power management features were enhanced through integration with suspend/resume cycles, enabling GPU state preservation during low-power states. The framework transitioned toward fully modular drivers, allowing of vendor code without recompiling the kernel. In April 2008, with Linux 2.6.25, the DRM core introduced a unified for consistent device interaction across drivers, while the pre-Kernel Mode Setting (KMS) era emphasized render-only nodes for secure, non-privileged GPU access focused on acceleration rather than display configuration.

Key Milestones and Recent Advances

The Graphics Execution Manager (GEM) was introduced in 2007-2008 as a kernel-level solution for managing graphics buffers, enabling efficient allocation and access to GPU memory without relying on user-space mechanisms. This framework was merged into the version 2.6.28, released in December 2008, marking a pivotal shift toward unified across diverse GPU architectures. Kernel Mode Setting (KMS) began its rollout in late 2008, allowing the kernel to handle display configuration independently of or user-space tools, which improved boot-time initialization and reduced reliance on blobs. Initial support landed in kernel 2.6.29 in March 2009, with broader adoption and stabilization occurring through 2010 across major drivers, enabling seamless mode switches and multi-monitor setups without X server intervention. Atomic modesetting emerged in 2012 with kernel 3.6, introducing a transaction-based approach to display updates that ensures page-flip atomicity for tear-free rendering by coordinating changes to CRTCs, planes, and connectors in a single commit. This feature, building on legacy modesetting, allowed applications to prepare complex state changes—like overlay adjustments and gamma corrections—atomically, minimizing visual artifacts in dynamic environments such as compositors. Render nodes were added in kernel 3.17 in 2014, decoupling render-only access from display control to enhance security by isolating unprivileged rendering tasks and supporting multi-GPU scenarios without exposing master device privileges. This separation prevented potential exploits in rendering paths from affecting display hardware, while facilitating better resource sharing in virtualized or containerized setups. In recent years, DRM has incorporated Rust-based drivers starting with 6.15 in May 2025, exemplified by the NOVA core for GPUs, which leverages Rust's to mitigate common kernel bugs like use-after-free in graphics handling. The fair DRM scheduler, merged in 2025, addresses equitable GPU time-sharing in multi-tenant environments by adopting a CFS-inspired algorithm that prevents and ensures low-latency clients receive fair cycles, improving throughput in shared cloud workloads. Additionally, dma-fence enhancements in kernel 6.17, released in October 2025, introduced safe access rules and new APIs for synchronization, reducing race conditions in buffer sharing across drivers like . A notable security milestone occurred in May 2025 with the patching of CVE-2025-37762 in the Virtio DRM driver, which fixed a dmabuf unpinning error in the framebuffer preparation path, bolstering isolation between virtualized guests and host resources to prevent memory leaks and potential escapes. DRM development is coordinated through the drm-next integration tree hosted on , where features undergo rigorous review before upstreaming to the mainline kernel, with major contributions from (e.g., i915 driver maintenance), (e.g., amdgpu enhancements), and partial support from via open-source components like Nouveau. This collaborative process, managed by the DRI project, ensures compatibility and stability across hardware vendors.

Software Architecture

Core API and Access Control

The Direct Rendering Manager (DRM) provides a foundational user-space that enables applications to interact with graphics hardware through the . User-space programs access this via ioctl() system calls on device files such as /dev/dri/card0, which serve as the primary entry points for , buffer allocation, and command submission to the GPU. This interface abstracts hardware-specific details, allowing drivers to expose consistent functionality while supporting extensions for vendor-specific needs. The 's design emphasizes security and isolation, ensuring that graphics operations are mediated by the kernel to prevent direct hardware access. As of 2025, the DRM subsystem has begun incorporating for driver development, enabling safer kernel modules with guarantees, as demonstrated in ongoing contributions to the graphics stack. Central to the DRM are key ioctls that handle , buffer , and basic device operations. For instance, DRM_IOCTL_GET_MAGIC authenticates clients by returning a unique magic token, which is essential for subsequent permission grants. Legacy buffer handling ioctls like DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS allow user-space to allocate and mark DMA buffers for rendering, though modern implementations often integrate with higher-level managers for these tasks. Vendor-specific ioctls, defined in driver headers (e.g., include/uapi/drm/i915_drm.h for ), extend the core without breaking compatibility. These ioctls are dispatched through a structured table in the drm_driver structure, ensuring orderly processing. Access control in DRM revolves around the DRM-Master concept, where a primary client—typically a display server like Xorg or Wayland compositor—obtains master status to hold exclusive rights for modesetting and display configuration. Secondary clients, such as render applications, must authenticate to the master using the magic token via DRM_IOCTL_AUTH_MAGIC to gain render access, preventing unauthorized GPU usage and enabling secure multi-client scenarios. This model enforces per-client isolation through file descriptors, where each open /dev/dri/card* instance maintains independent state, supporting multi-process environments without interference. The master can revoke permissions dynamically, ensuring robust control over shared resources. The has maintained stability since its introduction in kernel 2.6, with error handling standardized through negative return values (e.g., -ENODEV for device unavailability) and errno codes for specific failures like permission denials. Versioning is managed via DRM_IOCTL_VERSION, which reports the core level to user-space, allowing graceful handling of incompatibilities. Render nodes (/dev/dri/renderD*) further enhance isolation by providing non-master access solely for compute and rendering, bypassing modeset privileges and relying on for . Brief integration with buffer sharing extensions allows authenticated clients to map resources across processes, while operations often leverage GEM for efficient handling.

Graphics Execution Manager

The Graphics Execution Manager (GEM) serves as the primary layer within the Direct Rendering Manager (DRM) subsystem, providing an object-based model for handling GPU buffers in graphics drivers. Introduced as an Intel-sponsored initiative, GEM replaces the fragmented scatter-gather (DMA) approaches used in legacy DRM drivers, which often required frequent GPU reinitializations and led to inefficiencies in buffer handling. By abstracting buffers as kernel-managed objects, GEM enables more efficient allocation, sharing, and execution of graphics workloads, particularly on unified (UMA) devices where system RAM is shared between CPU and GPU. This model supports variable-size allocations, allowing drivers to request buffers of arbitrary page-aligned sizes without fixed granularity constraints. At its core, GEM represents GPU buffers as instances of the struct drm_gem_object, which drivers extend with private data for hardware-specific needs. These objects act as kernel-allocated handles referencing in video RAM (VRAM) or CPU-accessible system , depending on the driver implementation. Key operations—such as creation, mapping, and —are exposed through ioctls, including DRM_IOCTL_GEM_CREATE for allocating a new object with a specified size, DRM_IOCTL_GEM_MMAP for user-space mapping, and driver-specific calls for and domain transitions. Creation involves initializing the object via drm_gem_object_init() (typically backed by shmem for pageable CPU access) or drm_gem_private_object_init() for driver-managed storage, with via drm_gem_object_get() and drm_gem_object_put() ensuring proper lifetime management. Under pressure, GEM employs a least-recently-used (LRU) strategy through struct drm_gem_lru and shrinker mechanisms, using functions like drm_gem_evict_locked() to unpin and swap out non-resident objects, thereby freeing GPU aperture space. In the execution flow, user-space applications submit batches of commands to the GPU's ring buffers via driver ioctls (e.g., DRM_IOCTL_I915_GEM_EXECBUFFER in drivers), referencing GEM objects as inputs or outputs. GEM ensures object residency by binding them to the graphics translation table (GTT) or equivalent , handling migrations between CPU and GPU domains if needed, and enforcing through reservation objects (dma_resv) to prevent concurrent access. This process resolves relocations in command buffers and transitions memory domains (e.g., from CPU-writable to GPU-render), guaranteeing coherent execution without explicit user-space intervention. For drivers requiring advanced migration, Table Maps (TTM) can serve as an optional backend, providing generalized support for management, caching, and swapping between domains—capabilities beyond GEM's native UMA-focused design. Compared to TTM, adopts a simpler, more driver-centric approach tailored to rendering tasks, eschewing TTM's comprehensive VRAM management and multi-domain complexity in favor of streamlined UMA operations and minimal core overhead. While TTM excels in heterogeneous environments with features like automatic and placement policies, 's framework has made it the default for many drivers, such as Intel's i915, where TTM integration has been added as a backend for enhanced migration without altering the surface. This balance allows to prioritize performance in common rendering scenarios, such as improved frame rates in applications like (from 15.4 fps to 23.6 fps on 915 hardware) by reducing overhead in buffer setup and execution.

Kernel Mode Setting

Kernel Mode Setting (KMS) is a core component of the Direct Rendering Manager (DRM) subsystem in the , responsible for kernel-driven control of display hardware to configure screen resolutions, refresh rates, and output ports. By handling modesetting directly in the kernel space, KMS eliminates the need for user-space applications to load proprietary for basic display initialization, enabling faster boot times, seamless handoff to user-space compositors, and improved reliability across diverse hardware. Drivers initialize the KMS core by calling drmm_mode_config_init() on the DRM device, which sets up the foundational struct drm_device mode configuration. The KMS device model abstracts display hardware into interconnected entities: CRTCs (controllers that manage the timing and scanning of frames in the display pipeline), encoders (which convert digital signals to the format required by specific outputs), connectors (physical interfaces like or linking to monitors), and planes (independent layers for sourcing and blending pixel data, including primary framebuffers and overlays). These entities expose properties—such as modes, status, and capabilities—that userspace queries and modifies via ioctls; for example, DRM_IOCTL_MODE_GETRESOURCES retrieves the list of available CRTCs, encoders, and connectors to build a map. This model allows precise control over display pipelines while abstracting vendor-specific details. KMS provides two modesetting paradigms: the legacy approach, which applies changes through per-plane commits via individual ioctls like DRM_IOCTL_MODE_SET, and the , which offers a more advanced, transactional interface for coordinated updates. The atomic mode was introduced in 3.19, with full core support solidified by kernel 4.6, enabling userspace to propose a complete state change (via drm_atomic_state) that the kernel validates through an atomic check before applying it atomically to avoid partial failures. This facilitates advanced features, such as shadow planes for rendering updates off-screen before display to reduce tearing, and gamma lookup tables (LUTs) for per-CRTC color and brightness adjustments, improving efficiency in modern compositors. KMS incorporates mechanisms for dynamic display handling, including hotplug detection where changes in connector status trigger uevents to notify userspace of events like monitor connections or disconnections, allowing real-time reconfiguration. is supported via Display Power Management Signaling (DPMS) states—ON, STANDBY, SUSPEND, and OFF—applied to connectors to optimize energy use without full subsystem shutdown. Additionally, KMS handles topologies through properties like tile grouping for seamless large displays and suggested positioning ( coordinates) for logical arrangement across multiple CRTCs. KMS uses memory managers such as or TTM to allocate and manage scanout buffers, ensuring framebuffers are kernel-accessible for direct hardware rendering.

Buffer Management and Render Nodes

The Direct Rendering Manager (DRM) employs advanced buffer management techniques to facilitate efficient memory handling in pipelines, building upon underlying storage abstractions like GEM objects for allocation and manipulation. Central to this is the dma-buf subsystem, a generic kernel framework that enables the sharing of buffers across multiple device drivers and subsystems for (DMA) operations. Buffers are exported and imported using dma-buf file descriptors (fds), allowing seamless transfer without unnecessary copying, which is essential for performance-critical applications such as rendering and media processing. The PRIME protocol extends dma-buf specifically within DRM to support cross-device buffer sharing and render offloading, originally developed for multi-GPU platforms like . Introduced in 3.8 in 2012, PRIME allows applications to render on one GPU (e.g., a discrete dGPU) and display on another (e.g., an integrated iGPU) in heterogeneous setups, using ioctls such as DRM_IOCTL_PRIME_HANDLE_TO_FD to convert local handles to dma-buf fds and DRM_IOCTL_PRIME_FD_TO_HANDLE for the reverse. This enables operations, including video decoding pipelines where decoded frames from a V4L2 media driver can be directly imported into DRM for scanout without intermediate copies. To enhance security and isolation, DRM introduced render nodes in 3.12 in 2013, providing dedicated device files like /dev/dri/renderD* for compute-only access without modesetting privileges. Unlike primary nodes (/dev/dri/card*), which require master authentication for display control, render nodes restrict ioctls to non-privileged rendering commands, preventing unauthorized access to kernel mode setting (KMS) functions and mitigating risks from untrusted clients in multi-user or containerized environments. This separation supports secure off-screen rendering and GPGPU workloads while allowing broader access to GPU resources. Buffer operations in DRM rely on robust synchronization mechanisms to coordinate asynchronous GPU tasks, primarily through dma-fence objects that signal completion of hardware operations. These fences can be attached to buffers to ensure proper ordering, with dma-buf exporters managing attachments via the dma_buf_attach and dma_buf_map_attachment APIs. Recent enhancements in 2025, including fixes for dma-fence lifetime management in schedulers, have improved support for chainable fences (via dma_fence_chain), enabling more efficient sequencing of dependent operations in complex pipelines without risking use-after-free issues.

Hardware Support

Supported Graphics Vendors

The Direct Rendering Manager (DRM) subsystem in the supports a wide array of graphics hardware from major vendors through dedicated open-source drivers, enabling features like Kernel Mode Setting (KMS), () buffer objects, and atomic modesetting across compatible GPUs. Intel's integrated graphics are handled by the i915 driver, which has provided DRM support since kernel version 2.6.25 in 2008, though foundational work dates back to 2007. The i915 driver offers full KMS, , and atomic modeset compatibility, covering generations from (2011) through modern integrated GPUs like those in and Lunar Lake processors, as well as discrete Arc Alchemist and Battlemage cards up to 2025 releases. The Xe driver provides support for newer Intel architectures, including Battlemage discrete GPUs mainlined in kernel 6.12 (2024). AMD GPUs are supported via the amdgpu driver for modern hardware starting with kernel 4.2 in 2015 (fully mainlined around 4.6 in 2016 for Polaris-era RDNA and GCN architectures), alongside the legacy driver for pre-GCN cards. The amdgpu driver enables and acceleration through Mesa integration, with recent additions including support for RDNA4 architectures (e.g., RX 8000 series) in kernel 6.11 and later. NVIDIA hardware receives open-source support through the Nouveau driver, which has offered basic 2D and 3D acceleration via DRM since its inception in 2007 (merged in kernel 2.6.30). Nouveau provides limited reclocking and for , , and Tesla GPUs up to Turing and architectures, but full feature parity remains challenging due to reverse-engineering efforts. NVIDIA's proprietary driver supports DRM/KMS integration via the nvidia-drm kernel module (enabled with nvidia-drm.modeset=1) for modesetting and display management. For ARM-based systems, the Panfrost driver provides open-source DRM support for Mali GPUs based on Midgard, Bifrost, and Valhall architectures since kernel 4.19 in 2018. For newer CSF-based Mali hardware (Valhall CSF and later), the Panthor driver delivers support, merged in kernel 6.10 (2024). Vivante GPUs, common in embedded systems, are supported by the Etnaviv driver, which handles GC series cores for 2D/3D rendering and video decode. Additional vendors include via the vmwgfx driver for virtualized graphics in hosted environments and Virtio-GPU for paravirtualized acceleration in QEMU/KVM setups. Emerging support for GPUs is provided by the Freedreno driver, focusing on open-source for Snapdragon SoCs, though full coverage lags behind proprietary blobs. As of 6.17 (September 2025), the DRM subsystem includes over 20 active drivers, spanning discrete, integrated, and virtualized GPUs, with ongoing additions in 6.18; however, gaps persist for proprietary implementations, particularly full reclocking and advanced features on non-open hardware.

Driver Implementation Details

DRM drivers are structured around the core struct drm_driver, which defines a set of mandatory and optional callbacks to interface with the DRM subsystem. For Graphics Execution Manager (GEM) support, drivers must implement essential callbacks such as .gem_init to initialize GEM-specific resources during device probe, ensuring buffer object management is set up correctly. Similarly, for Kernel Mode Setting (KMS), the struct drm_mode_config_funcs requires implementations like .mode_valid to validate display modes against hardware constraints, preventing invalid configurations from being applied. Optional callbacks, such as those for (e.g., .suspend and .resume in the driver ops), allow drivers to handle system suspend/resume cycles, though they are not required for basic functionality. Memory management in DRM drivers commonly relies on two backends: the Translation Table Manager (TTM) and . TTM serves as the primary backend for drivers handling dedicated video RAM, such as the driver for hardware and VMware's virtual GPU drivers, providing eviction, migration, and placement policies for complex memory hierarchies. In contrast, 's i915 driver employs a driver-local GEM implementation, leveraging (shmem) for unified memory architecture (UMA) devices, which simplifies allocation without TTM's overhead for integrated graphics. The Xe driver follows a similar approach for newer hardware. Vendor-specific extensions enhance DRM drivers with hardware-unique features. In the Intel i915 driver, GuC (Graphics Micro-Controller) and HuC (HEVC Micro-Controller) firmware loading is managed by the kernel, where the driver authenticates and initializes the HuC firmware for media acceleration while relying on GuC for workload scheduling and submission. AMD's amdgpu driver integrates (RAS) features for error reporting, exposing uncorrectable (UE) and correctable (CE) error counts via interfaces and debugfs for injection and control, enabling proactive fault detection in environments. For Arm Mali GPUs, the Panthor driver (for CSF-based hardware) utilizes job submission queues in the Command Stream Frontend (CSF), allowing batched job dispatching to the firmware for efficient compute and graphics workloads. Recent advancements include the first Rust-based DRM driver, NOVA for GPUs, providing core infrastructure merged in 6.15. The virtio-gpu driver gained enhanced support in 6.15, including panic screen compatibility for better debugging in virtualized environments. Additionally, the Fair DRM Scheduler, integrated in kernel 6.16 (July 2025), introduces timeslicing inspired by the (CFS), improving fairness and reducing latency in multi-client scenarios for drivers like amdgpu and nouveau by eliminating multiple run queues and prioritizing interactive workloads. Debugging DRM drivers involves kernel-exposed interfaces and userspace tools. The drm_info utility queries device properties and capabilities via ioctls, while debugfs mounts (e.g., under /sys/kernel/debug/dri/) expose driver-specific files for runtime inspection, such as queue states or firmware logs. GPU hangs, often detected via watchdog timeouts, trigger driver-initiated resets to recover the device, with the DRM core coordinating fence signaling and context cleanup to minimize impact on userspace. A key operational principle of DRM is User API (UAPI) stability, which guarantees that kernel-user interfaces remain backward-compatible across driver versions. New UAPI additions require accompanying open-source userspace implementations (e.g., in Mesa) to be reviewed and merged upstream first, ensuring no regressions; this policy, enforced through tests like IGT, allows userspace applications to interact reliably with evolving kernel drivers without breakage.

Adoption and Integration

Usage in Desktop and Mobile Environments

In desktop environments such as and , the Direct Rendering Manager (DRM) serves as a foundational component for graphics rendering and display management, particularly through integration with Wayland compositors that leverage Kernel Mode Setting (KMS) for direct scanout of buffers to the display without intermediate copying. This enables efficient, hardware-accelerated composition, where applications render directly to GPU-managed buffers that are then flipped atomically to the screen, reducing overhead in modern sessions. For legacy Xorg-based setups, DRM provides a fallback via modesetting support, allowing the X server to utilize KMS for mode changes and buffer management while maintaining compatibility with older workflows. In mobile and embedded systems, DRM is extensively utilized in distributions like Yocto for building custom images and in Android Open Source Project (AOSP) for graphics acceleration, where it handles buffer allocation and submission to support SurfaceFlinger, the Android compositor. System-on-Chips (SoCs) from vendors such as and Allwinner rely on DRM drivers to interface with display outputs like MIPI DSI panels and connectors, enabling seamless video pipeline configuration in resource-constrained environments such as tablets and single-board computers. These implementations facilitate hardware-accelerated decoding and rendering, critical for power-efficient media playback and UI responsiveness in embedded applications. DRM contributes to performance benefits in gaming scenarios on desktops, where tools like Proton leverage APIs over DRM to achieve reduced input latency by directly submitting command buffers to the GPU, bypassing unnecessary CPU involvement in the render path. Additionally, atomic mode setting in DRM enables tear-free display updates through synchronized page flips, ensuring smooth frame delivery during high-frame-rate gaming without visual artifacts. However, challenges arise in hybrid graphics configurations common to laptops, where PRIME render offload—used to switch rendering between integrated and discrete GPUs—can encounter issues with synchronization and under DRM, such as incomplete buffer handoff leading to glitches or suboptimal battery life. Since around 2010, DRM-enabled drivers have become ubiquitous in major distributions like and , powering graphics in the vast majority of Linux desktop installations with modern GPUs. A notable recent development is the 2025 Request for Comments (RFC) for the Splash DRM client, which proposes a kernel-level interface for rendering boot-time splash screens directly via DRM, enhancing early graphics initialization in both desktop and embedded boot processes.

Extensions and Ecosystem Impact

The Direct Rendering Manager (DRM) supports extensions that integrate with advanced graphics and compute APIs, notably through the Mesa 3D graphics library, which enables rendering directly on DRM's kernel interfaces for efficient without intermediary window systems. extensions like VK_KHR_display and VK_EXT_image_drm_format_modifier allow applications to import DRM buffer objects for rendering, facilitating seamless operation on platforms. Similarly, Intel's OneAPI framework leverages DRM via Mesa for general-purpose GPU computing on integrated graphics, providing access to for and other workloads. In virtualization environments, DRM pairs with VFIO to enable GPU passthrough, where virtual machines gain direct control over physical GPUs through DRM's device nodes, enhancing performance for graphics-intensive guest applications. Within the broader ecosystem, DRM's DMA-BUF framework has significantly influenced compatibility and portability efforts. It underpins Wine and Proton by allowing shared buffer access between DirectX translation layers (via ) and native drivers, enabling high-fidelity execution of Windows games on desktops. DRM also impacts Android development through the migration from the legacy ION allocator to DMA-BUF heaps, standardizing buffer sharing across graphics drivers and reducing fragmentation in mobile kernels; this shift, completed in and later, aligns Android's graphics stack more closely with upstream DRM/KMS for better hardware support. Security features in DRM emphasize isolation and mitigation strategies to protect against vulnerabilities. Render nodes provide per-client device files that isolate rendering operations, preventing unprivileged processes from accessing master DRM controls and reducing the attack surface for graphics exploits. This isolation has been crucial in addressing CVEs, such as CVE-2025-40096, a double free vulnerability in the DRM scheduler related to job dependency reference handling that could lead to memory corruption, with patches fixing the issue. Additionally, SELinux integrates hooks into DRM operations to enforce mandatory access controls on device nodes and buffer allocations, blocking unauthorized kernel interactions. Looking ahead, DRM is expanding Rust-based driver development to enhance across all graphics drivers, with ongoing efforts including a dedicated development tree and ports like Nova and . DRM supports advanced workloads through driver-specific extensions that enable GPU compute capabilities. DRM's ecosystem impact extends to server and BSD environments, powering (VDI) on a majority of servers by providing robust modesetting and buffer sharing for remote graphics delivery. It has influenced ports to and DragonFlyBSD, where kernel teams adapt DRM code for native support of modern GPUs, including updates to KMS drivers from 4.20 equivalents for improved hardware compatibility. Community governance in DRM relies on the drm-misc-next branch for collaborative development, where maintainers integrate pull requests from global contributors during merge windows, ensuring rigorous review of features like atomic modesetting extensions before upstreaming to the mainline kernel. This process fosters open participation while maintaining stability for the ecosystem.

References

Add your contribution
Related Hubs
User Avatar
No comments yet.