요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. Copyright 2020 DisplayLink (UK) Ltd.
===================
Userland interfaces
===================
The DRM core exports several interfaces to applications, generally
intended to be used through corresponding libdrm wrapper functions. In
addition, drivers export device-specific interfaces for use by userspace
drivers & 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.
Cover generic ioctls and sysfs layout here. We only need high-level
info, since man pages should cover the rest.
libdrm Device Lookup
====================
.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c
:doc: getunique and setversion story
.. _drm_primary_node:
Primary Nodes, DRM Master and Authentication
============================================
.. kernel-doc:: drivers/gpu/drm/drm_auth.c
:doc: master and authentication
.. kernel-doc:: drivers/gpu/drm/drm_auth.c
:export:
.. kernel-doc:: include/drm/drm_auth.h
:internal:
.. _drm_leasing:
DRM Display Resource Leasing
============================
.. kernel-doc:: drivers/gpu/drm/drm_lease.c
:doc: drm leasing
Open-Source Userspace Requirements
==================================
The DRM subsystem has stricter requirements than most other kernel subsystems on
what the userspace side for new uAPI needs to look like. This section here
explains what exactly those requirements are, and why they exist.
The short summary is that any addition of DRM uAPI requires corresponding
open-sourced userspace patches, and those patches must be reviewed and ready for
merging into a suitable and canonical upstream project.
GFX devices (both display and render/GPU side) are really complex bits of
hardware, with userspace and kernel by necessity having to work together really
closely. The interfaces, for rendering and modesetting, must be extremely wide
and flexible, and therefore it is almost always impossible to precisely define
them for every possible corner case. This in turn makes it really practically
infeasible to differentiate between behaviour that's required by userspace, and
which must not be changed to avoid regressions, and behaviour which is only an
accidental artifact of the current implementation.
Without access to the full source code of all userspace users that means it
becomes impossible to change the implementation details, since userspace could
depend upon the accidental behaviour of the current implementation in minute
details. And debugging such regressions without access to source code is pretty
much impossible. As a consequence this means:
- The Linux kernel's "no regression" policy holds in practice only for
open-source userspace of the DRM subsystem. DRM developers are perfectly fine
if closed-source blob drivers in userspace use the same uAPI as the open
drivers, 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, lead
to breakage.
- Any new userspace interface must have an open-source implementation as
demonstration vehicle.
The other reason for requiring open-source userspace is uAPI review. Since the
kernel and userspace parts of a GFX stack must work together so closely, code
review can only assess whether a new interface achieves its goals by looking at
both sides. Making sure that the interface indeed covers the use-case fully
leads to a few additional requirements:
- The open-source userspace must not be a toy/test application, but the real
thing. 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 to
assess the fitness of a proposed interface.
- The userspace side must be fully reviewed and tested to the standards of that
userspace project. For e.g. mesa this means piglit testcases and review on the
mailing list. This is again to ensure that the new interface actually gets the
job done. The userspace-side reviewer should also provide an Acked-by on the
kernel uAPI patch indicating that they believe the proposed uAPI is sound and
sufficiently documented and validated for userspace's consumption.
- The userspace patches must be against the canonical upstream, not some vendor
fork. This is to make sure that no one cheats on the review and testing
requirements by doing a quick fork.
- The kernel patch can only be merged after all the above requirements are met,
but it **must** be merged to either drm-next or drm-misc-next **before** the
userspace patches land. uAPI always flows from the kernel, doing things the
other way round risks divergence of the uAPI definitions and header files.
These are fairly steep requirements, but have grown out from years of shared
pain and experience with uAPI added hastily, and almost always regretted about
just as fast. GFX devices change really fast, requiring a paradigm shift and
entire new set of uAPI interfaces every few years at least. Together with the
Linux kernel's guarantee to keep existing userspace running for 10+ years this
is already rather painful for the DRM subsystem, with multiple different uAPIs
for the same thing co-existing. If we add a few more complete mistakes into the
mix every year it would be entirely unmanageable.
.. _drm_render_node:
Render nodes
============
DRM core provides multiple character-devices for user-space to use.
Depending on which device is opened, user-space can perform a different
set of operations (mainly ioctls). The primary node is always created
and called card<num>. Additionally, a currently unused control node,
called controlD<num> is also created. The primary node provides all
legacy operations and historically was the only interface used by
userspace. With KMS, the control node was introduced. However, the
planned KMS control interface has never been written and so the control
node stays unused to date.
With the increased use of offscreen renderers and GPGPU applications,
clients no longer require running compositors or graphics servers to
make use of a GPU. But the DRM API required unprivileged clients to
authenticate to a DRM-Master prior to getting GPU access. To avoid this
step and to grant clients GPU access without authenticating, render
nodes were introduced. Render nodes solely serve render clients, that
is, no modesetting or privileged ioctls can be issued on render nodes.
Only non-global rendering commands are allowed. If a driver supports
render nodes, it must advertise it via the DRIVER_RENDER DRM driver
capability. If not supported, the primary node must be used for render
clients together with the legacy drmAuth authentication procedure.
If a driver advertises render node support, DRM core will create a
separate render node called renderD<num>. There will be one render node
per device. No ioctls except PRIME-related ioctls will be allowed on
this node. Especially GEM_OPEN will be explicitly prohibited. For a
complete list of driver-independent ioctls that can be used on render
nodes, see the ioctls marked DRM_RENDER_ALLOW in drm_ioctl.c Render
nodes are designed to avoid the buffer-leaks, which occur if clients
guess the flink names or mmap offsets on the legacy interface.
Additionally to this basic interface, drivers must mark their
driver-dependent render-only ioctls as DRM_RENDER_ALLOW so render
clients can use them. Driver authors must be careful not to allow any
privileged ioctls on render nodes.
With render nodes, user-space can now control access to the render node
via basic file-system access-modes. A running graphics server which
authenticates clients on the privileged primary/legacy node is no longer
required. Instead, a client can open the render node and is immediately
granted GPU access. Communication between clients (or servers) is done
via PRIME. FLINK from render node to legacy node is not supported. New
clients must not use the insecure FLINK interface.
Besides dropping all modeset/global ioctls, render nodes also drop the
DRM-Master concept. There is no reason to associate render clients with
a DRM-Master as they are independent of any graphics server. Besides,
they must work without any running master, anyway. Drivers must be able
to run without a master object if they support render nodes. If, on the
other hand, a driver requires shared state between clients which is
visible to user-space and accessible beyond open-file boundaries, they
cannot 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 end
user is able to hot-unplug this kind of devices while they are being
used, and expects that the very least the machine does not crash. Any
damage from hot-unplugging a DRM device needs to be limited as much as
possible and userspace must be given the chance to handle it if it wants
to. Ideally, unplugging a DRM device still lets a desktop continue to
run, but that is going to need explicit support throughout the whole
graphics stack: from kernel and userspace drivers, through display
servers, via window system protocols, and in applications and libraries.
Other scenarios that should lead to the same are: unrecoverable GPU
crash, PCI device disappearing off the bus, or forced unbind of a driver
from the physical device.
In other words, from userspace perspective everything needs to keep on
working more or less, until userspace stops using the disappeared DRM
device and closes it completely. Userspace will learn of the device
disappearance 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 file
descriptors and removed all mmaps, the DRM driver can tear down its
instance for the device that no longer exists. If the same physical
device somehow comes back in the mean time, it shall be a new DRM
device.
Similar to PIDs, chardev minor numbers are not recycled immediately. A
new DRM device always picks the next free minor number compared to the
previous one allocated, and wraps around when minor numbers are
exhausted.
The goal raises at least the following requirements for the kernel and
drivers.
Requirements for KMS UAPI
-------------------------
- KMS connectors must change their status to disconnected.
- Legacy modesets and pageflips, and atomic commits, both real and
TEST_ONLY, and any other ioctls either fail with ENODEV or fake
success.
- Pending non-blocking KMS operations deliver the DRM events userspace
is expecting. This applies also to ioctls that faked success.
- open() on a device node whose underlying device has disappeared will
fail with ENXIO.
- Attempting to create a DRM lease on a disappeared DRM device will
fail with ENODEV. Existing DRM leases remain and work as listed
above.
Requirements for Render and Cross-Device UAPI
---------------------------------------------
- All GPU jobs that can no longer run must have their fences
force-signalled to avoid inflicting hangs on userspace.
The associated error code is ENODEV.
- Some userspace APIs already define what should happen when the device
disappears (OpenGL, GL ES: `GL_KHR_robustness`_; `Vulkan`_:
VK_ERROR_DEVICE_LOST; etc.). DRM drivers are free to implement this
behaviour the way they see best, e.g. returning failures in
driver-specific ioctls and handling those in userspace drivers, or
rely on uevents, and so on.
- dmabuf which point to memory that has disappeared will either fail to
import with ENODEV or continue to be successfully imported if it would
have succeeded before the disappearance. See also about memory maps
below for already imported dmabufs.
- Attempting to import a dmabuf to a disappeared device will either fail
with ENODEV or succeed if it would have succeeded without the
disappearance.
- open() on a device node whose underlying device has disappeared will
fail with ENXIO.
.. _GL_KHR_robustness: https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_robustness.txt
.. _Vulkan: https://www.khronos.org/vulkan/
Requirements for Memory Maps
----------------------------
Memory maps have further requirements that apply to both existing maps
and maps created after the device has disappeared. If the underlying
memory disappears, the map is created or modified such that reads and
writes will still complete successfully but the result is undefined.
This applies to both userspace mmap()'d memory and memory pointed to by
dmabuf which might be mapped to other devices (cross-device dmabuf
imports).
Raising SIGBUS is not an option, because userspace cannot realistically
handle it. Signal handlers are global, which makes them extremely
difficult to use correctly from libraries like those that Mesa produces.
Signal handlers are not composable, you can't have different handlers
for GPU1 and GPU2 from different vendors, and a third handler for
mmapped regular files. Threads cause additional pain with signal
handling 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 errors
require resetting the device in order to make the device usable again. This
section describes the expectations for DRM and usermode drivers when a
device resets and how to propagate the reset status.
Device resets can not be disabled without tainting the kernel, which can lead to
hanging the entire kernel through shrinkers/mmu_notifiers. Userspace role in
device resets is to propagate the message to the application and apply any
special policy for blocking guilty applications, if any. Corollary is that
debugging a hung GPU context require hardware support to be able to preempt such
a GPU context while it's stopped.
Kernel Mode Driver
------------------
The KMD is responsible for checking if the device needs a reset, and to perform
it 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 in
the opposite direction of the usual flow of commands. Because of this vendor
independent error handling was added to the &dma_fence object, this way drivers
can add an error code to their fences before signaling them. See function
dma_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 when
hardware submissions are restarted after an reset. Error codes are also
forwarded from the hardware fence to the scheduler fence to bubble up errors
to the higher levels of the stack and eventually userspace.
Fence errors can be queried by userspace through the generic SYNC_IOC_FILE_INFO
IOCTL as well as through driver specific interfaces.
Additional to setting fence errors drivers should also keep track of resets per
context, the DRM scheduler provides the drm_sched_entity_error() function as
helper for this use case. After a reset, KMD should reject new command
submissions for affected contexts.
User Mode Driver
----------------
After command submission, UMD should check if the submission was accepted or
rejected. After a reset, KMD should reject submissions, and UMD can issue an
ioctl to the KMD to check the reset status, and this can be checked more often
if the UMD requires it. After detecting a reset, UMD will then proceed to report
it to the application using the appropriate API error code, as explained in the
section below about robustness.
Robustness
----------
The only way to try to keep a graphical API context working after a reset is if
it 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 a
userspace that doesn't support robust interfaces (like a non-robust
OpenGL context or API without any robustness support like libva) leave the
robustness handling entirely to the userspace driver. There is no strong
community 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 the
extension ``GL_ARB_robustness`` (or ``GL_EXT_robustness`` for OpenGL ES). This
interface tells if a reset has happened, and if so, all the context state is
considered lost and the app proceeds by creating new ones. There's no consensus
on what to do to if robustness is not in use.
Vulkan
~~~~~~
Apps using Vulkan should check for ``VK_ERROR_DEVICE_LOST`` for submissions.
This error code means, among other things, that a device reset has happened and
it 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's
really useful for driver developers to learn more about what caused the reset in
the first place. For this, drivers can make use of devcoredump to store relevant
information about the reset and send device wedged event with ``none`` recovery
method (as explained in "Device Wedging" chapter) to notify userspace, so this
information can be collected and added to user bug reports.
Device Wedging
==============
Drivers can optionally make use of device wedged event (implemented as
drm_dev_wedged_event() in DRM subsystem), which notifies userspace of 'wedged'
(hanged/unusable) state of the DRM device through a uevent. This is useful
especially in cases where the device is no longer operating as expected and has
become unrecoverable from driver context. Purpose of this implementation is to
provide drivers a generic way to recover the device with the help of userspace
intervention, without taking any drastic measures (like resetting or
re-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 driver
after exhausting all possible attempts to recover it from driver context. The
uevent is the notification that is sent to userspace along with a hint about
what could possibly be attempted to recover the device from userspace and bring
it back to usable state. Different drivers may have different ideas of a
'wedged' device depending on hardware implementation of the underlying physical
device, and hence the vendor agnostic nature of the event. It is up to the
drivers to decide when they see the need for device recovery and how they want
to 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 any
communication channels with other devices. Further, the driver must ensure
that all dma_fences are signalled and any device state that the core kernel
might depend on is cleaned up. All existing mmaps should be invalidated and
page faults should be redirected to a dummy page. Once the event is sent, the
device must be kept in 'wedged' state until the recovery is performed. New
accesses to the device (IOCTLs) should be rejected, preferably with an error
code that resembles the type of failure the device has encountered. This will
signify the reason for wedging, which can be reported to the application if
needed.
Recovery
--------
Current implementation defines four recovery methods, out of which, drivers
can use any one, multiple or none. Method(s) of choice will be sent in the
uevent environment as ``WEDGED=<method1>[,..,<methodN>]`` in order of less to
more side-effects. See the section `Vendor Specific Recovery`_
for ``WEDGED=vendor-specific``. If driver is unsure about recovery or
method is unknown, ``WEDGED=unknown`` will be sent instead.
Userspace consumers can parse this event and attempt recovery as per the
following 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 is ``WEDGED=none``, which signifies that the device
was temporarily 'wedged' at some point but was recovered from driver context
using device specific methods like reset. No explicit recovery is expected from
the consumer in this case, but it can still take additional steps like gathering
telemetry information (devcoredump, syslog). This is useful because the first
hang is usually the most critical one which can result in consequential hangs or
complete wedging.
Vendor Specific Recovery
------------------------
When ``WEDGED=vendor-specific`` is sent, it indicates that the device requires
a recovery procedure specific to the hardware vendor and is not one of the
standardized approaches.
``WEDGED=vendor-specific`` may be used to indicate different cases within a
single vendor driver, each requiring a distinct recovery procedure.
In such scenarios, the vendor driver must provide comprehensive documentation
that describes each case, include additional hints to identify specific case and
outline the corresponding recovery procedure. The documentation includes:
Case - A list of all cases that sends the ``WEDGED=vendor-specific`` recovery method.
Hints - Additional Information to assist the userspace consumer in identifying and
differentiating 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 and
verify additional identification hints before attempting a recovery procedure.
Example: If the device uses the Xe driver, then userspace consumer should refer to
:ref:`Xe Device Wedging <xe-device-wedging>` for the detailed documentation.
Task information
----------------
The information about which application (if any) was involved in the device
wedging is useful for userspace if they want to notify the user about what
happened (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 task
information is available, the uevent will display as ``PID=<pid>`` and
``TASK=<task name>``. Otherwise, ``PID`` and ``TASK`` will not appear in the
event string.
The reliability of this information is driver and hardware specific, and should
be taken with a caution regarding it's precision. To have a big picture of what
really happened, the devcoredump file provides much more detailed information
about the device state and about the event.
Consumer prerequisites
----------------------
It is the responsibility of the consumer to make sure that the device or its
resources are not in use by any process before attempting recovery. With IOCTLs
erroring out, all device memory should be unmapped and file descriptors should
be closed to prevent leaks or undefined behaviour. The idea here is to clear the
device of all user context beforehand and set the stage for a clean recovery.
For ``WEDGED=vendor-specific`` recovery method, it is the responsibility of the
consumer to check the driver documentation and the usecase before attempting
a 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/sh
DEVPATH=$(readlink -f /sys/$1/device)
DEVICE=$(basename $DEVPATH)
DRIVER=$(readlink -f $DEVPATH/driver)
echo -n $DEVICE > $DRIVER/unbind
echo -n $DEVICE > $DRIVER/bind
Customization
-------------
Although basic recovery is possible with a simple script, consumers can define
custom policies around recovery. For example, if the driver supports multiple
recovery methods, consumers can opt for the suitable one depending on scenarios
like repeat offences or vendor specific failures. Consumers can also choose to
have the device available for debugging or telemetry collection and base their
recovery decision on the findings. This is useful especially when the driver is
unsure about recovery or method is unknown.
.. _drm_driver_ioctl:
IOCTL Support on Device Nodes
=============================
.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c
:doc: driver specific ioctls
Recommended IOCTL Return Values
-------------------------------
In theory a driver's IOCTL callback is only allowed to return very few error
codes. In practice it's good to abuse a few more. This section documents common
practice within the DRM subsystem:
ENOENT:
Strictly this should only be used when a file doesn't exist e.g. when
calling the open() syscall. We reuse that to signal any kind of object
lookup failure, e.g. for unknown GEM buffer object handles, unknown KMS
object handles and similar cases.
ENOSPC:
Some drivers use this to differentiate "out of kernel memory" from "out
of VRAM". Sometimes also applies to other limited gpu resources used for
rendering (e.g. when you have a special limited compression buffer).
Sometimes resource allocation/reservation issues in command submission
IOCTLs 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 return
this when called by unpriviledged clients. There's no clear
difference 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 used
when the exporting driver of a shared dma-buf or fence doesn't support a
feature needed.
EINTR:
DRM drivers assume that userspace restarts all IOCTLs. Any DRM IOCTL can
return EINTR and in such a case should be restarted with the IOCTL
parameters left unchanged.
EIO:
The GPU died and couldn't be resurrected through a reset. Modesetting
hardware failures are signalled through the "link status" connector
property.
EINVAL:
Catch-all for anything that is an invalid argument combination which
cannot work.
IOCTL also use other error codes like ETIME, EFAULT, EBUSY, ENOTTY but their
usage is in line with the common meanings. The above list tries to just document
DRM specific patterns. Note that ENOTTY has the slightly unintuitive meaning of
"this IOCTL does not exist", and is used exactly as such in DRM.
.. kernel-doc:: include/drm/drm_ioctl.h
:internal:
.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c
:export:
.. kernel-doc:: drivers/gpu/drm/drm_ioc32.c
:export:
Testing and validation
======================
Testing Requirements for userspace API
--------------------------------------
New cross-driver userspace interface extensions, like new IOCTL, new KMS
properties, new files in sysfs or anything else that constitutes an API change
should have driver-agnostic testcases in IGT for that feature, if such a test
can 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 of
DRM drivers and that can be used to check that changes to DRM drivers or the
core don't regress existing functionality. This test suite is called IGT and
its code and instructions to build and run can be found in
https://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 testing
and for running compositors. VKMS aims to enable a virtual display without
the need for a hardware display capability. These characteristics made VKMS
a perfect tool for validating the DRM core behavior and also support the
compositor developer. VKMS makes it possible to test DRM functions in a
virtual machine without display, simplifying the validation of some of the
core changes.
To Validate changes in DRM API with VKMS, start setting the kernel: make
sure to enable VKMS module; compile the kernel with the VKMS enabled and
install 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 minimum
of 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 with
the 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 saves
them in the folder "igt-gpu-tools/results". It executes only the igt-tests
matching the -t option.
Display CRC Support
-------------------
.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c
:doc: CRC ABI
.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c
:export:
Debugfs Support
---------------
.. kernel-doc:: include/drm/drm_debugfs.h
:internal:
.. kernel-doc:: drivers/gpu/drm/drm_debugfs.c
:export:
Sysfs Support
=============
.. kernel-doc:: drivers/gpu/drm/drm_sysfs.c
:doc: overview
.. kernel-doc:: drivers/gpu/drm/drm_sysfs.c
:export:
VBlank event handling
=====================
The DRM core exposes two vertical blank related ioctls:
:c:macro:`DRM_IOCTL_WAIT_VBLANK`
This takes a struct drm_wait_vblank structure as its argument, and
it is used to block or request a signal when a specified vblank
event occurs.
:c:macro:`DRM_IOCTL_MODESET_CTL`
This was only used for user-mode-settind drivers around modesetting
changes to allow the kernel to update the vblank interrupt after
mode setting, since on many devices the vertical blank counter is
reset to 0 at some point during modeset. Modern drivers should not
call this any more since with kernel mode setting it is a no-op.
Userspace API Structures
========================
.. kernel-doc:: include/uapi/drm/drm_mode.h
:doc: overview
.. _crtc_index:
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 is
needed, for instance a bitmask of CRTC's. The member possible_crtcs of struct
drm_mode_get_plane is an example.
:c:macro:`DRM_IOCTL_MODE_GETRESOURCES` populates a structure with an array of
CRTC ID's, and the CRTC index is its position in this array.
.. kernel-doc:: include/uapi/drm/drm.h
:internal:
.. kernel-doc:: include/uapi/drm/drm_mode.h
:internal:
dma-buf interoperability
========================
Please see Documentation/userspace-api/dma-buf-alloc-exchange.rst for
information on how dma-buf is integrated and exposed within DRM.
Trace events
============
See Documentation/trace/tracepoints.rst for information about using
Linux Kernel Tracepoints.
In the DRM subsystem, some events are considered stable uAPI to avoid
breaking tools (e.g.: GPUVis, umr) relying on them. Stable means that fields
cannot be removed, nor their formatting updated. Adding new fields is
possible, under the normal uAPI requirements.
Stable uAPI events
------------------
From ``drivers/gpu/drm/scheduler/gpu_scheduler_trace.h``
.. kernel-doc:: drivers/gpu/drm/scheduler/gpu_scheduler_trace.h
:doc: uAPI trace events
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Userland interface, DRM master·authentication과 lease
1-48DRM core는 application에 여러 interface를 export하며 일반적으로 대응하는 `libdrm` wrapper function을 통해 사용합니다. Driver는 device-specific userspace driver와 device-aware application을 위해 ioctl과 sysfs file로 고유 interface도 export합니다.
외부 interface에는 memory mapping, context·DMA·AGP 관리, vblank control, fence·memory·output 관리가 포함됩니다. 이 문서는 generic ioctl과 sysfs layout의 상위 수준 정보만 다루며 세부사항은 man page의 역할입니다.
`libdrm Device Lookup`은 `drm_ioctl.c`의 getunique·setversion history를 포함합니다. Primary node 절은 DRM master와 authentication 개요·exported API·내부 header를, display resource leasing 절은 `drm_lease.c`의 lease 문서를 제공합니다.
Core와 driver가 userspace에 노출하는 기능을 구분합니다.
Device lookup, primary node master/auth와 display lease의 5개 block입니다.
.. Copyright 2020 DisplayLink (UK) Ltd.
===================
Userland interfaces
===================
The DRM core exports several interfaces to applications, generally
intended to be used through corresponding libdrm wrapper functions. In
addition, drivers export device-specific interfaces for use by userspace
drivers & 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.
Cover generic ioctls and sysfs layout here. We only need high-level
info, since man pages should cover the rest.
libdrm Device Lookup
====================
.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c
:doc: getunique and setversion story
.. _drm_primary_node:
Primary Nodes, DRM Master and Authentication
============================================
.. kernel-doc:: drivers/gpu/drm/drm_auth.c
:doc: master and authentication
.. kernel-doc:: drivers/gpu/drm/drm_auth.c
:export:
.. kernel-doc:: include/drm/drm_auth.h
:internal:
.. _drm_leasing:
DRM Display Resource Leasing
============================
.. kernel-doc:: drivers/gpu/drm/drm_lease.c
:doc: drm leasing
Open-source userspace가 필요한 이유와 merge 순서
49-122DRM subsystem은 새 uAPI의 userspace 측 구현에 대해 대부분의 kernel subsystem보다 엄격한 요구사항을 둡니다. 요약하면 DRM uAPI를 추가할 때 대응하는 open-source userspace patch가 있어야 하고, 적절한 canonical upstream project에 merge할 준비가 되도록 review를 마쳐야 합니다.
Display와 render/GPU를 포함한 GFX device는 매우 복잡하고 userspace와 kernel이 긴밀하게 협력해야 합니다. Rendering·modesetting interface는 폭넓고 유연해야 하므로 모든 corner case를 정확히 정의하기 거의 불가능합니다. 따라서 userspace가 반드시 의존하는 동작과 현재 구현의 우연한 artifact를 구분하기 어렵습니다.
모든 userspace source에 접근할 수 없으면 폐쇄형 userspace가 사소한 우연적 동작에 의존할 수 있어 구현 세부사항을 변경할 수 없고 regression debug도 사실상 불가능합니다. Linux kernel의 no-regression 정책은 DRM에서는 실제로 open-source userspace에 대해서만 유지됩니다. Closed-source blob이 같은 uAPI를 써도 되지만 open driver와 정확히 같은 방식으로 사용해야 하며 interface를 창의적으로 오용하면 깨질 수 있습니다.
새 userspace interface에는 반드시 실제 open-source 구현이 demonstration vehicle로 있어야 합니다. Toy/test application이 아니라 일반 error와 corner case를 모두 처리하는 실제 구현이어야 새 uAPI의 적합성을 평가할 수 있습니다.
Userspace 측은 해당 project 기준으로 review와 test를 완료해야 합니다. Mesa라면 piglit testcase와 mailing-list review가 필요하며 userspace reviewer는 제안 uAPI가 충분히 문서화·검증되었다는 뜻의 `Acked-by`를 kernel uAPI patch에도 제공해야 합니다.
Userspace patch는 vendor fork가 아니라 canonical upstream을 대상으로 해야 합니다. Kernel patch는 모든 요구사항이 충족된 뒤에만 merge할 수 있지만 userspace patch가 들어가기 전에 `drm-next` 또는 `drm-misc-next`에 먼저 merge되어야 합니다. uAPI는 항상 kernel에서 흘러나와야 definition과 header가 갈라지는 위험을 막을 수 있습니다.
이 요구사항은 성급하게 추가한 uAPI로 겪은 오랜 문제에서 생겼습니다. GFX hardware는 빠르게 변해 몇 년마다 새로운 paradigm과 uAPI가 필요하지만 kernel은 10년 이상 기존 userspace 동작을 보장합니다. 같은 기능의 여러 uAPI가 공존하는 상황에서 잘못된 interface까지 계속 추가하면 관리할 수 없습니다.
Kernel과 userspace 양쪽에서 충족해야 하는 순서와 품질 기준입니다.
Open-Source Userspace Requirements
==================================
The DRM subsystem has stricter requirements than most other kernel subsystems on
what the userspace side for new uAPI needs to look like. This section here
explains what exactly those requirements are, and why they exist.
The short summary is that any addition of DRM uAPI requires corresponding
open-sourced userspace patches, and those patches must be reviewed and ready for
merging into a suitable and canonical upstream project.
GFX devices (both display and render/GPU side) are really complex bits of
hardware, with userspace and kernel by necessity having to work together really
closely. The interfaces, for rendering and modesetting, must be extremely wide
and flexible, and therefore it is almost always impossible to precisely define
them for every possible corner case. This in turn makes it really practically
infeasible to differentiate between behaviour that's required by userspace, and
which must not be changed to avoid regressions, and behaviour which is only an
accidental artifact of the current implementation.
Without access to the full source code of all userspace users that means it
becomes impossible to change the implementation details, since userspace could
depend upon the accidental behaviour of the current implementation in minute
details. And debugging such regressions without access to source code is pretty
much impossible. As a consequence this means:
- The Linux kernel's "no regression" policy holds in practice only for
open-source userspace of the DRM subsystem. DRM developers are perfectly fine
if closed-source blob drivers in userspace use the same uAPI as the open
drivers, 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, lead
to breakage.
- Any new userspace interface must have an open-source implementation as
demonstration vehicle.
The other reason for requiring open-source userspace is uAPI review. Since the
kernel and userspace parts of a GFX stack must work together so closely, code
review can only assess whether a new interface achieves its goals by looking at
both sides. Making sure that the interface indeed covers the use-case fully
leads to a few additional requirements:
- The open-source userspace must not be a toy/test application, but the real
thing. 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 to
assess the fitness of a proposed interface.
- The userspace side must be fully reviewed and tested to the standards of that
userspace project. For e.g. mesa this means piglit testcases and review on the
mailing list. This is again to ensure that the new interface actually gets the
job done. The userspace-side reviewer should also provide an Acked-by on the
kernel uAPI patch indicating that they believe the proposed uAPI is sound and
sufficiently documented and validated for userspace's consumption.
- The userspace patches must be against the canonical upstream, not some vendor
fork. This is to make sure that no one cheats on the review and testing
requirements by doing a quick fork.
- The kernel patch can only be merged after all the above requirements are met,
but it **must** be merged to either drm-next or drm-misc-next **before** the
userspace patches land. uAPI always flows from the kernel, doing things the
other way round risks divergence of the uAPI definitions and header files.
These are fairly steep requirements, but have grown out from years of shared
pain and experience with uAPI added hastily, and almost always regretted about
just as fast. GFX devices change really fast, requiring a paradigm shift and
entire new set of uAPI interfaces every few years at least. Together with the
Linux kernel's guarantee to keep existing userspace running for 10+ years this
is already rather painful for the DRM subsystem, with multiple different uAPIs
for the same thing co-existing. If we add a few more complete mistakes into the
mix every year it would be entirely unmanageable.
.. _drm_render_node:
Primary·control·render node와 권한 모델
123-177DRM core는 userspace가 사용할 여러 character device를 제공합니다. 어떤 node를 여느냐에 따라 사용할 operation, 주로 ioctl 집합이 달라집니다. Primary node `card<num>`는 항상 생성되고 모든 legacy operation을 제공합니다. `controlD<num>` control node도 생성되지만 계획했던 KMS control interface가 구현되지 않아 현재 사용하지 않습니다.
Offscreen renderer와 GPGPU application이 늘면서 GPU 사용에 compositor나 graphics server가 필요하지 않게 되었습니다. 기존 DRM API는 unprivileged client가 GPU access 전에 DRM master에 authentication하도록 했지만, 이 단계를 없애기 위해 render node가 도입되었습니다.
Render node는 render client만 지원하므로 modesetting과 privileged ioctl을 허용하지 않고 non-global rendering command만 허용합니다. Driver는 `DRIVER_RENDER` capability를 광고해야 합니다. 지원하지 않으면 render client도 primary node와 legacy `drmAuth` 절차를 사용해야 합니다.
지원 시 device마다 `renderD<num>` node 하나가 생성됩니다. Driver-independent ioctl 중 PRIME 관련 ioctl과 `drm_ioctl.c`에서 `DRM_RENDER_ALLOW`로 표시된 것만 허용하며 `GEM_OPEN`은 명시적으로 금지됩니다. Driver-specific render-only ioctl도 `DRM_RENDER_ALLOW`로 표시해야 하고 privileged ioctl을 허용하지 않도록 주의해야 합니다.
Render node는 filesystem access mode로 권한을 제어하고 open 즉시 GPU access를 부여하므로 client를 인증하는 graphics server가 필요 없습니다. Client 간 공유는 PRIME을 사용하며 render node에서 legacy node로 FLINK하는 것은 지원하지 않습니다. 새 client는 안전하지 않은 FLINK를 사용하면 안 됩니다.
Render node에는 DRM master 개념도 없습니다. Driver는 master object 없이 동작할 수 있어야 합니다. Open-file 경계를 넘어 userspace에 보이고 client가 공유하는 state가 꼭 필요한 driver는 render node를 지원할 수 없습니다.
Node별 목적과 허용 operation입니다.
DRM master authentication 없이 안전한 rendering access를 제공합니다.
Render nodes
============
DRM core provides multiple character-devices for user-space to use.
Depending on which device is opened, user-space can perform a different
set of operations (mainly ioctls). The primary node is always created
and called card<num>. Additionally, a currently unused control node,
called controlD<num> is also created. The primary node provides all
legacy operations and historically was the only interface used by
userspace. With KMS, the control node was introduced. However, the
planned KMS control interface has never been written and so the control
node stays unused to date.
With the increased use of offscreen renderers and GPGPU applications,
clients no longer require running compositors or graphics servers to
make use of a GPU. But the DRM API required unprivileged clients to
authenticate to a DRM-Master prior to getting GPU access. To avoid this
step and to grant clients GPU access without authenticating, render
nodes were introduced. Render nodes solely serve render clients, that
is, no modesetting or privileged ioctls can be issued on render nodes.
Only non-global rendering commands are allowed. If a driver supports
render nodes, it must advertise it via the DRIVER_RENDER DRM driver
capability. If not supported, the primary node must be used for render
clients together with the legacy drmAuth authentication procedure.
If a driver advertises render node support, DRM core will create a
separate render node called renderD<num>. There will be one render node
per device. No ioctls except PRIME-related ioctls will be allowed on
this node. Especially GEM_OPEN will be explicitly prohibited. For a
complete list of driver-independent ioctls that can be used on render
nodes, see the ioctls marked DRM_RENDER_ALLOW in drm_ioctl.c Render
nodes are designed to avoid the buffer-leaks, which occur if clients
guess the flink names or mmap offsets on the legacy interface.
Additionally to this basic interface, drivers must mark their
driver-dependent render-only ioctls as DRM_RENDER_ALLOW so render
clients can use them. Driver authors must be careful not to allow any
privileged ioctls on render nodes.
With render nodes, user-space can now control access to the render node
via basic file-system access-modes. A running graphics server which
authenticates clients on the privileged primary/legacy node is no longer
required. Instead, a client can open the render node and is immediately
granted GPU access. Communication between clients (or servers) is done
via PRIME. FLINK from render node to legacy node is not supported. New
clients must not use the insecure FLINK interface.
Besides dropping all modeset/global ioctls, render nodes also drop the
DRM-Master concept. There is no reason to associate render clients with
a DRM-Master as they are independent of any graphics server. Besides,
they must work without any running master, anyway. Drivers must be able
to run without a master object if they support render nodes. If, on the
other hand, a driver requires shared state between clients which is
visible to user-space and accessible beyond open-file boundaries, they
cannot support render nodes.
Hot-unplug 후 KMS·render·mmap 계약
178-287이 절은 2020년 5월 기준 구현 완료가 아닌 계획임을 명시합니다. USB display adapter·dock이나 Thunderbolt eGPU는 사용 중 hot-unplug될 수 있으며 최소한 system이 crash하지 않아야 합니다. Damage를 제한하고 userspace가 처리할 기회를 줘야 하며 이상적으로 desktop이 계속 동작하려면 kernel/userspace driver, display server, window protocol, application과 library 전체의 명시적 지원이 필요합니다.
복구 불가능한 GPU crash, PCI bus에서 device 소실, physical device에서 driver 강제 unbind도 같은 동작으로 이어져야 합니다. Userspace가 사라진 DRM device 사용을 멈추고 완전히 닫을 때까지 나머지 기능은 대체로 계속 동작해야 합니다.
Userspace는 device-removed uevent, `ENODEV`를 반환하는 ioctl, driver-specific 오류, `ENXIO`를 반환하는 `open()`으로 소실을 알게 됩니다. 관련 DRM device·dma-buf fd를 모두 닫고 mmap을 제거한 뒤에만 driver가 instance를 해체할 수 있습니다. Physical device가 다시 나타나면 새 DRM device로 취급합니다. Character-device minor는 PID처럼 즉시 재사용하지 않고 다음 free number를 선택하며 소진되면 wrap합니다.
Userspace resource가 남아 있는 동안 instance를 유지한 뒤 안전하게 해체합니다.
KMS connector는 disconnected로 바뀌어야 합니다. Legacy modeset·pageflip, real·`TEST_ONLY` atomic commit과 기타 ioctl은 `ENODEV`로 실패하거나 성공을 가장해야 합니다. 성공을 가장한 경우를 포함해 pending nonblocking operation은 userspace가 기대하는 DRM event를 전달해야 합니다. 사라진 node의 `open()`은 `ENXIO`, 새 lease 생성은 `ENODEV`이며 기존 lease는 위 규칙에 따라 유지됩니다.
Display UAPI가 사라진 device를 처리하는 방식입니다.
더는 실행할 수 없는 GPU job의 fence는 userspace hang을 막기 위해 `ENODEV` error로 force-signal해야 합니다. OpenGL·OpenGL ES의 `GL_KHR_robustness`, Vulkan의 `VK_ERROR_DEVICE_LOST`처럼 device 소실 동작을 이미 정의한 API는 driver-specific ioctl, uevent 등 적절한 방법으로 구현할 수 있습니다.
사라진 memory를 가리키는 dma-buf는 import가 `ENODEV`로 실패하거나 소실 전 성공했을 경우 계속 성공할 수 있습니다. 사라진 device로 dma-buf를 import하는 경우도 같은 선택입니다. 기존·신규 memory map에서 backing memory가 사라지면 read/write는 성공적으로 끝나되 결과는 undefined여야 합니다. Userspace mmap과 다른 device에 mapping된 cross-device dma-buf 모두에 적용됩니다.
`SIGBUS`는 현실적으로 userspace가 처리할 수 없어 사용할 수 없습니다. Signal handler는 process 전역이고 library에서 올바르게 사용하기 매우 어려우며 vendor가 다른 GPU1·GPU2와 일반 mmap file에 서로 다른 handler를 합성할 수 없습니다. Thread도 signal handling을 더 어렵게 합니다.
Display 외 UAPI가 device disappearance를 전파하는 계약입니다.
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 end
user is able to hot-unplug this kind of devices while they are being
used, and expects that the very least the machine does not crash. Any
damage from hot-unplugging a DRM device needs to be limited as much as
possible and userspace must be given the chance to handle it if it wants
to. Ideally, unplugging a DRM device still lets a desktop continue to
run, but that is going to need explicit support throughout the whole
graphics stack: from kernel and userspace drivers, through display
servers, via window system protocols, and in applications and libraries.
Other scenarios that should lead to the same are: unrecoverable GPU
crash, PCI device disappearing off the bus, or forced unbind of a driver
from the physical device.
In other words, from userspace perspective everything needs to keep on
working more or less, until userspace stops using the disappeared DRM
device and closes it completely. Userspace will learn of the device
disappearance 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 file
descriptors and removed all mmaps, the DRM driver can tear down its
instance for the device that no longer exists. If the same physical
device somehow comes back in the mean time, it shall be a new DRM
device.
Similar to PIDs, chardev minor numbers are not recycled immediately. A
new DRM device always picks the next free minor number compared to the
previous one allocated, and wraps around when minor numbers are
exhausted.
The goal raises at least the following requirements for the kernel and
drivers.
Requirements for KMS UAPI
-------------------------
- KMS connectors must change their status to disconnected.
- Legacy modesets and pageflips, and atomic commits, both real and
TEST_ONLY, and any other ioctls either fail with ENODEV or fake
success.
- Pending non-blocking KMS operations deliver the DRM events userspace
is expecting. This applies also to ioctls that faked success.
- open() on a device node whose underlying device has disappeared will
fail with ENXIO.
- Attempting to create a DRM lease on a disappeared DRM device will
fail with ENODEV. Existing DRM leases remain and work as listed
above.
Requirements for Render and Cross-Device UAPI
---------------------------------------------
- All GPU jobs that can no longer run must have their fences
force-signalled to avoid inflicting hangs on userspace.
The associated error code is ENODEV.
- Some userspace APIs already define what should happen when the device
disappears (OpenGL, GL ES: `GL_KHR_robustness`_; `Vulkan`_:
VK_ERROR_DEVICE_LOST; etc.). DRM drivers are free to implement this
behaviour the way they see best, e.g. returning failures in
driver-specific ioctls and handling those in userspace drivers, or
rely on uevents, and so on.
- dmabuf which point to memory that has disappeared will either fail to
import with ENODEV or continue to be successfully imported if it would
have succeeded before the disappearance. See also about memory maps
below for already imported dmabufs.
- Attempting to import a dmabuf to a disappeared device will either fail
with ENODEV or succeed if it would have succeeded without the
disappearance.
- open() on a device node whose underlying device has disappeared will
fail with ENXIO.
.. _GL_KHR_robustness: https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_robustness.txt
.. _Vulkan: https://www.khronos.org/vulkan/
Requirements for Memory Maps
----------------------------
Memory maps have further requirements that apply to both existing maps
and maps created after the device has disappeared. If the underlying
memory disappears, the map is created or modified such that reads and
writes will still complete successfully but the result is undefined.
This applies to both userspace mmap()'d memory and memory pointed to by
dmabuf which might be mapped to other devices (cross-device dmabuf
imports).
Raising SIGBUS is not an option, because userspace cannot realistically
handle it. Signal handlers are global, which makes them extremely
difficult to use correctly from libraries like those that Mesa produces.
Signal handlers are not composable, you can't have different handlers
for GPU1 and GPU2 from different vendors, and a third handler for
mmapped regular files. Threads cause additional pain with signal
handling as well.
Device reset과 robustness error propagation
288-378GPU stack은 hardware bug, 잘못된 application과 여러 layer의 오류에 취약하며 device를 다시 사용하려면 reset이 필요할 수 있습니다. 이 절은 DRM과 user-mode driver가 reset 상태를 전파하는 방식을 설명합니다.
Kernel을 taint하지 않고 device reset을 비활성화할 수는 없습니다. 비활성화하면 shrinker·mmu_notifier를 통해 kernel 전체가 hang할 수 있습니다. Userspace는 reset message를 application에 전달하고 필요하면 원인 application 차단 policy를 적용합니다. 멈춘 GPU context를 debug하려면 정지 상태에서도 context를 preempt할 hardware 지원이 필요합니다.
KMD는 reset 필요 여부를 검사하고 필요하면 수행합니다. 보통 job 실행이 멈추면 hang을 감지합니다. Error는 command 흐름과 반대 방향으로 전파되므로 `dma_fence_set_error()`로 `dma_fence`에 vendor-independent error code를 넣고 signal합니다.
DRM scheduler는 reset 뒤 hardware submission을 재시작할 때 pending fence 전체에 error를 설정할 수 있고 hardware fence의 error를 scheduler fence로 전달해 stack 상위와 userspace까지 올립니다. Userspace는 generic `SYNC_IOC_FILE_INFO` 또는 driver-specific interface로 fence error를 조회합니다. KMD는 `drm_sched_entity_error()`로 context별 reset을 추적하고 영향받은 context의 새 command submission을 거부해야 합니다.
UMD는 command submission이 accepted인지 rejected인지 확인해야 합니다. Reset 뒤 KMD가 submission을 거부하면 UMD는 ioctl로 reset status를 확인하고 graphical API에 맞는 error code로 application에 보고합니다.
Reset 뒤 context를 계속 쓰려면 해당 graphical API의 robustness 규칙을 따라야 합니다. Non-robust OpenGL context나 robustness가 없는 libva 같은 API는 처리를 userspace driver에 전적으로 맡기며 합리적인 선택마다 단점이 있어 community consensus가 없습니다.
OpenGL application은 `GL_ARB_robustness`, OpenGL ES는 `GL_EXT_robustness`를 사용해야 합니다. Reset이 발생하면 context state 전체가 lost로 간주되어 새 context를 만듭니다. Vulkan application은 submission의 `VK_ERROR_DEVICE_LOST`를 확인하고 context를 재생성해야 합니다.
Reset 원인 분석을 위해 driver는 devcoredump에 관련 정보를 저장하고 recovery method가 `none`인 device-wedged event를 보내 userspace가 수집해 bug report에 첨부하도록 할 수 있습니다.
Hardware hang에서 graphical API error까지 fence를 통해 전달합니다.
Application이 reset 뒤 context를 처리하는 규칙입니다.
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 errors
require resetting the device in order to make the device usable again. This
section describes the expectations for DRM and usermode drivers when a
device resets and how to propagate the reset status.
Device resets can not be disabled without tainting the kernel, which can lead to
hanging the entire kernel through shrinkers/mmu_notifiers. Userspace role in
device resets is to propagate the message to the application and apply any
special policy for blocking guilty applications, if any. Corollary is that
debugging a hung GPU context require hardware support to be able to preempt such
a GPU context while it's stopped.
Kernel Mode Driver
------------------
The KMD is responsible for checking if the device needs a reset, and to perform
it 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 in
the opposite direction of the usual flow of commands. Because of this vendor
independent error handling was added to the &dma_fence object, this way drivers
can add an error code to their fences before signaling them. See function
dma_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 when
hardware submissions are restarted after an reset. Error codes are also
forwarded from the hardware fence to the scheduler fence to bubble up errors
to the higher levels of the stack and eventually userspace.
Fence errors can be queried by userspace through the generic SYNC_IOC_FILE_INFO
IOCTL as well as through driver specific interfaces.
Additional to setting fence errors drivers should also keep track of resets per
context, the DRM scheduler provides the drm_sched_entity_error() function as
helper for this use case. After a reset, KMD should reject new command
submissions for affected contexts.
User Mode Driver
----------------
After command submission, UMD should check if the submission was accepted or
rejected. After a reset, KMD should reject submissions, and UMD can issue an
ioctl to the KMD to check the reset status, and this can be checked more often
if the UMD requires it. After detecting a reset, UMD will then proceed to report
it to the application using the appropriate API error code, as explained in the
section below about robustness.
Robustness
----------
The only way to try to keep a graphical API context working after a reset is if
it 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 a
userspace that doesn't support robust interfaces (like a non-robust
OpenGL context or API without any robustness support like libva) leave the
robustness handling entirely to the userspace driver. There is no strong
community 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 the
extension ``GL_ARB_robustness`` (or ``GL_EXT_robustness`` for OpenGL ES). This
interface tells if a reset has happened, and if so, all the context state is
considered lost and the app proceeds by creating new ones. There's no consensus
on what to do to if robustness is not in use.
Vulkan
~~~~~~
Apps using Vulkan should check for ``VK_ERROR_DEVICE_LOST`` for submissions.
This error code means, among other things, that a device reset has happened and
it 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's
really useful for driver developers to learn more about what caused the reset in
the first place. For this, drivers can make use of devcoredump to store relevant
information about the reset and send device wedged event with ``none`` recovery
method (as explained in "Device Wedging" chapter) to notify userspace, so this
information can be collected and added to user bug reports.
Device wedging event와 userspace recovery
379-539Driver는 `drm_dev_wedged_event()`로 device가 hung/unusable한 wedged state임을 uevent로 알릴 수 있습니다. Driver context에서 복구할 수 없을 때 userspace 도움으로 device를 회복하되 driver가 전체 bus를 reset·재열거하는 과격한 조치를 직접 하지 않도록 하는 vendor-agnostic interface입니다.
Wedged device는 driver가 가능한 복구 시도를 모두 소진한 뒤 dead로 선언한 device입니다. Uevent는 userspace가 시도할 recovery hint를 함께 전달합니다. Hardware 구현에 따라 wedged의 의미가 다르므로 driver가 recovery 시점과 사용 가능한 method를 결정합니다.
Recovery 전에 driver는 system 전체를 보호해야 합니다. System memory DMA와 다른 device의 communication channel을 끄고 모든 `dma_fence`를 signal하며 core kernel이 의존하는 state를 정리해야 합니다. Existing mmap은 invalidate하고 page fault는 dummy page로 redirect합니다. Event 뒤 recovery까지 wedged state를 유지하고 새 ioctl access는 failure 유형에 가까운 error code로 거부해야 합니다.
Userspace recovery를 요청하기 전에 driver가 system을 격리합니다.
Recovery method는 side effect가 적은 순서로 `WEDGED=<method1>[,..,<methodN>]`에 담깁니다. Driver는 `none`, `rebind`, `bus-reset`, `vendor-specific` 중 하나 이상 또는 아무 것도 선택할 수 있고 불명확하면 `unknown`을 보냅니다.
Uevent 값과 consumer가 기대하는 동작입니다.
`WEDGED=none`은 device가 일시적으로 wedged였으나 reset 같은 device-specific 방식으로 driver가 이미 복구했음을 뜻합니다. 명시적 recovery는 필요 없지만 첫 hang이 후속 hang이나 완전한 wedging의 원인이 될 수 있으므로 devcoredump·syslog telemetry를 수집할 수 있습니다.
`WEDGED=vendor-specific`은 표준 방법이 아닌 vendor hardware 고유 절차가 필요함을 뜻하며 한 driver 안에서도 여러 case를 나타낼 수 있습니다. Driver 문서는 모든 case, sysfs·debugfs·trace·dmesg 등 case를 구분할 hint, 필요한 script·tool을 포함한 명확한 recovery procedure를 제공해야 합니다. Admin/consumer는 case와 hint를 확인한 뒤 실행해야 합니다. Xe의 예는 `Xe Device Wedging <xe-device-wedging>` 문서를 참조합니다.
Wedging에 관련된 application 정보가 있으면 uevent에 `PID=<pid>`와 `TASK=<task name>`이 나타납니다. Userspace는 사용자 알림이나 반복 reset task 차단 policy에 활용할 수 있지만 정확도는 driver·hardware에 따라 다르므로 주의해야 합니다. 전체 상황은 devcoredump가 더 자세히 제공합니다.
Recovery 결정과 원인 분석에 쓰는 uevent·telemetry field입니다.
Consumer는 recovery 전에 어떤 process도 device나 resource를 사용하지 않게 해야 합니다. 실패하는 ioctl 뒤 모든 device memory를 unmap하고 fd를 닫아 leak과 undefined behavior를 막고 user context를 제거합니다. Vendor-specific method는 driver 문서와 use case를 확인해야 합니다.
`rebind` 예시는 다음 udev rule과 recovery script를 사용합니다.
SUBSYSTEM=="drm", ENV{WEDGED}=="rebind", DEVPATH=="*/drm/card[0-9]",
RUN+="/path/to/rebind.sh $env{DEVPATH}"
#!/bin/sh
DEVPATH=$(readlink -f /sys/$1/device)
DEVICE=$(basename $DEVPATH)
DRIVER=$(readlink -f $DEVPATH/driver)
echo -n $DEVICE > $DRIVER/unbind
echo -n $DEVICE > $DRIVER/bind
Consumer는 반복 offense, vendor failure 등 상황에 따라 여러 method 중 하나를 고르거나 device를 debug·telemetry 수집 상태로 남겨 결과에 따라 recovery를 결정하는 custom policy를 만들 수 있습니다. Driver가 recovery를 확신하지 못하거나 method가 unknown일 때 특히 유용합니다.
Device Wedging
==============
Drivers can optionally make use of device wedged event (implemented as
drm_dev_wedged_event() in DRM subsystem), which notifies userspace of 'wedged'
(hanged/unusable) state of the DRM device through a uevent. This is useful
especially in cases where the device is no longer operating as expected and has
become unrecoverable from driver context. Purpose of this implementation is to
provide drivers a generic way to recover the device with the help of userspace
intervention, without taking any drastic measures (like resetting or
re-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 driver
after exhausting all possible attempts to recover it from driver context. The
uevent is the notification that is sent to userspace along with a hint about
what could possibly be attempted to recover the device from userspace and bring
it back to usable state. Different drivers may have different ideas of a
'wedged' device depending on hardware implementation of the underlying physical
device, and hence the vendor agnostic nature of the event. It is up to the
drivers to decide when they see the need for device recovery and how they want
to 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 any
communication channels with other devices. Further, the driver must ensure
that all dma_fences are signalled and any device state that the core kernel
might depend on is cleaned up. All existing mmaps should be invalidated and
page faults should be redirected to a dummy page. Once the event is sent, the
device must be kept in 'wedged' state until the recovery is performed. New
accesses to the device (IOCTLs) should be rejected, preferably with an error
code that resembles the type of failure the device has encountered. This will
signify the reason for wedging, which can be reported to the application if
needed.
Recovery
--------
Current implementation defines four recovery methods, out of which, drivers
can use any one, multiple or none. Method(s) of choice will be sent in the
uevent environment as ``WEDGED=<method1>[,..,<methodN>]`` in order of less to
more side-effects. See the section `Vendor Specific Recovery`_
for ``WEDGED=vendor-specific``. If driver is unsure about recovery or
method is unknown, ``WEDGED=unknown`` will be sent instead.
Userspace consumers can parse this event and attempt recovery as per the
following 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 is ``WEDGED=none``, which signifies that the device
was temporarily 'wedged' at some point but was recovered from driver context
using device specific methods like reset. No explicit recovery is expected from
the consumer in this case, but it can still take additional steps like gathering
telemetry information (devcoredump, syslog). This is useful because the first
hang is usually the most critical one which can result in consequential hangs or
complete wedging.
Vendor Specific Recovery
------------------------
When ``WEDGED=vendor-specific`` is sent, it indicates that the device requires
a recovery procedure specific to the hardware vendor and is not one of the
standardized approaches.
``WEDGED=vendor-specific`` may be used to indicate different cases within a
single vendor driver, each requiring a distinct recovery procedure.
In such scenarios, the vendor driver must provide comprehensive documentation
that describes each case, include additional hints to identify specific case and
outline the corresponding recovery procedure. The documentation includes:
Case - A list of all cases that sends the ``WEDGED=vendor-specific`` recovery method.
Hints - Additional Information to assist the userspace consumer in identifying and
differentiating 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 and
verify additional identification hints before attempting a recovery procedure.
Example: If the device uses the Xe driver, then userspace consumer should refer to
:ref:`Xe Device Wedging <xe-device-wedging>` for the detailed documentation.
Task information
----------------
The information about which application (if any) was involved in the device
wedging is useful for userspace if they want to notify the user about what
happened (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 task
information is available, the uevent will display as ``PID=<pid>`` and
``TASK=<task name>``. Otherwise, ``PID`` and ``TASK`` will not appear in the
event string.
The reliability of this information is driver and hardware specific, and should
be taken with a caution regarding it's precision. To have a big picture of what
really happened, the devcoredump file provides much more detailed information
about the device state and about the event.
Consumer prerequisites
----------------------
It is the responsibility of the consumer to make sure that the device or its
resources are not in use by any process before attempting recovery. With IOCTLs
erroring out, all device memory should be unmapped and file descriptors should
be closed to prevent leaks or undefined behaviour. The idea here is to clear the
device of all user context beforehand and set the stage for a clean recovery.
For ``WEDGED=vendor-specific`` recovery method, it is the responsibility of the
consumer to check the driver documentation and the usecase before attempting
a 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/sh
DEVPATH=$(readlink -f /sys/$1/device)
DEVICE=$(basename $DEVPATH)
DRIVER=$(readlink -f $DEVPATH/driver)
echo -n $DEVICE > $DRIVER/unbind
echo -n $DEVICE > $DRIVER/bind
Customization
-------------
Although basic recovery is possible with a simple script, consumers can define
custom policies around recovery. For example, if the driver supports multiple
recovery methods, consumers can opt for the suitable one depending on scenarios
like repeat offences or vendor specific failures. Consumers can also choose to
have the device available for debugging or telemetry collection and base their
recovery decision on the findings. This is useful especially when the driver is
unsure about recovery or method is unknown.
.. _drm_driver_ioctl:
Device node ioctl과 권장 errno
540-612Driver-specific ioctl reference 뒤에는 DRM ioctl callback의 일반적인 return value 관례를 정리합니다. 이론상 허용 error code는 적지만 DRM에서는 공통 의미를 확장해 사용합니다.
DRM-specific 관례와 일반 kernel 의미를 구분합니다.
Command submission의 allocation·reservation 문제는 `EDEADLK`로 나타날 수도 있습니다. `ETIME`, `EFAULT`, `EBUSY` 등 다른 code는 일반 의미대로 사용합니다. DRM ioctl은 언제든 `EINTR`를 반환할 수 있고 userspace는 argument를 그대로 두고 재시작해야 합니다.
Driver-specific ioctl 설명, 내부 declaration, native·compat exported API의 4개 block입니다.
IOCTL Support on Device Nodes
=============================
.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c
:doc: driver specific ioctls
Recommended IOCTL Return Values
-------------------------------
In theory a driver's IOCTL callback is only allowed to return very few error
codes. In practice it's good to abuse a few more. This section documents common
practice within the DRM subsystem:
ENOENT:
Strictly this should only be used when a file doesn't exist e.g. when
calling the open() syscall. We reuse that to signal any kind of object
lookup failure, e.g. for unknown GEM buffer object handles, unknown KMS
object handles and similar cases.
ENOSPC:
Some drivers use this to differentiate "out of kernel memory" from "out
of VRAM". Sometimes also applies to other limited gpu resources used for
rendering (e.g. when you have a special limited compression buffer).
Sometimes resource allocation/reservation issues in command submission
IOCTLs 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 return
this when called by unpriviledged clients. There's no clear
difference 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 used
when the exporting driver of a shared dma-buf or fence doesn't support a
feature needed.
EINTR:
DRM drivers assume that userspace restarts all IOCTLs. Any DRM IOCTL can
return EINTR and in such a case should be restarted with the IOCTL
parameters left unchanged.
EIO:
The GPU died and couldn't be resurrected through a reset. Modesetting
hardware failures are signalled through the "link status" connector
property.
EINVAL:
Catch-all for anything that is an invalid argument combination which
cannot work.
IOCTL also use other error codes like ETIME, EFAULT, EBUSY, ENOTTY but their
usage is in line with the common meanings. The above list tries to just document
DRM specific patterns. Note that ENOTTY has the slightly unintuitive meaning of
"this IOCTL does not exist", and is used exactly as such in DRM.
.. kernel-doc:: include/drm/drm_ioctl.h
:internal:
.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c
:export:
.. kernel-doc:: drivers/gpu/drm/drm_ioc32.c
:export:
IGT와 VKMS를 이용한 UAPI 검증
613-669새 ioctl, KMS property, sysfs file처럼 cross-driver userspace interface를 확장하는 API 변경에는 target hardware에서 IGT로 합리적으로 test할 수 있다면 driver-agnostic IGT testcase가 있어야 합니다.
IGT는 DRM driver와 core의 전체 기능을 다루고 regression을 확인하는 test suite입니다. Code와 build·실행 지침은 `https://gitlab.freedesktop.org/drm/igt-gpu-tools/`에서 제공합니다.
VKMS는 hardware display 없이 virtual display를 제공하는 software-only KMS driver model입니다. DRM core 동작과 compositor를 검증하고 display가 없는 virtual machine에서도 DRM function을 test할 수 있습니다.
VKMS module을 활성화한 kernel을 build해 target에 설치하고 QEMU·virtme 같은 VM에서 실행합니다. KVM, 최소 RAM 1GB와 4 core를 권장합니다. IGT는 VM 내부에서 직접 실행하거나 host에서 실행해 shared directory에 결과를 기록할 수 있습니다.
$ virtme-run --rwdir /path/for/shared_dir --kdir=path/for/kernel/directory --mods=auto
$ /path/for/igt-gpu-tools/scripts/run-tests.sh -p -s -t "kms_flip.*" -v
예시는 `kms_flip.*` test만 실행합니다. `-p` option으로 `igt_runner` 대신 Piglit을 사용해 HTML summary를 만들고 `igt-gpu-tools/results`에 저장하며 `-t`와 일치하는 test만 실행합니다.
새 UAPI와 core 변경을 검증하는 도구별 역할입니다.
Testing and validation
======================
Testing Requirements for userspace API
--------------------------------------
New cross-driver userspace interface extensions, like new IOCTL, new KMS
properties, new files in sysfs or anything else that constitutes an API change
should have driver-agnostic testcases in IGT for that feature, if such a test
can 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 of
DRM drivers and that can be used to check that changes to DRM drivers or the
core don't regress existing functionality. This test suite is called IGT and
its code and instructions to build and run can be found in
https://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 testing
and for running compositors. VKMS aims to enable a virtual display without
the need for a hardware display capability. These characteristics made VKMS
a perfect tool for validating the DRM core behavior and also support the
compositor developer. VKMS makes it possible to test DRM functions in a
virtual machine without display, simplifying the validation of some of the
core changes.
To Validate changes in DRM API with VKMS, start setting the kernel: make
sure to enable VKMS module; compile the kernel with the VKMS enabled and
install 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 minimum
of 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 with
the 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 saves
them in the folder "igt-gpu-tools/results". It executes only the igt-tests
matching the -t option.
CRC·debugfs·sysfs, vblank와 CRTC index
670-740Display CRC support는 `drm_debugfs_crc.c`의 CRC ABI와 exported API를 제공합니다. Debugfs support는 header 내부 interface와 implementation API를, sysfs support는 overview와 exported API를 제공합니다.
DRM core는 vertical blank 관련 ioctl 두 개를 노출합니다. `DRM_IOCTL_WAIT_VBLANK`는 `struct drm_wait_vblank`을 받아 지정 vblank event가 발생할 때 block하거나 signal을 요청합니다.
`DRM_IOCTL_MODESET_CTL`은 과거 user-mode-setting driver가 modeset 뒤 vblank interrupt를 갱신하도록 사용했습니다. 많은 device가 modeset 중 vblank counter를 0으로 reset하기 때문입니다. 현대 kernel mode setting driver에서는 no-op이므로 호출하면 안 됩니다.
Legacy와 현재 사용 가능한 vertical blank interface를 구분합니다.
Userspace API structure는 `include/uapi/drm/drm_mode.h` overview와 `drm.h`·`drm_mode.h` 내부 문서를 제공합니다. CRTC에는 object ID와 별개의 index가 있습니다. Index는 CRTC bitmask처럼 조밀한 식별자가 필요할 때 쓰며 `drm_mode_get_plane.possible_crtcs`가 예입니다.
`DRM_IOCTL_MODE_GETRESOURCES`가 채우는 CRTC ID array에서 CRTC index는 해당 ID의 array 위치입니다.
Display validation interface와 public mode structure의 9개 block입니다.
Display CRC Support
-------------------
.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c
:doc: CRC ABI
.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c
:export:
Debugfs Support
---------------
.. kernel-doc:: include/drm/drm_debugfs.h
:internal:
.. kernel-doc:: drivers/gpu/drm/drm_debugfs.c
:export:
Sysfs Support
=============
.. kernel-doc:: drivers/gpu/drm/drm_sysfs.c
:doc: overview
.. kernel-doc:: drivers/gpu/drm/drm_sysfs.c
:export:
VBlank event handling
=====================
The DRM core exposes two vertical blank related ioctls:
:c:macro:`DRM_IOCTL_WAIT_VBLANK`
This takes a struct drm_wait_vblank structure as its argument, and
it is used to block or request a signal when a specified vblank
event occurs.
:c:macro:`DRM_IOCTL_MODESET_CTL`
This was only used for user-mode-settind drivers around modesetting
changes to allow the kernel to update the vblank interrupt after
mode setting, since on many devices the vertical blank counter is
reset to 0 at some point during modeset. Modern drivers should not
call this any more since with kernel mode setting it is a no-op.
Userspace API Structures
========================
.. kernel-doc:: include/uapi/drm/drm_mode.h
:doc: overview
.. _crtc_index:
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 is
needed, for instance a bitmask of CRTC's. The member possible_crtcs of struct
drm_mode_get_plane is an example.
:c:macro:`DRM_IOCTL_MODE_GETRESOURCES` populates a structure with an array of
CRTC ID's, and the CRTC index is its position in this array.
.. kernel-doc:: include/uapi/drm/drm.h
:internal:
.. kernel-doc:: include/uapi/drm/drm_mode.h
:internal:
dma-buf interoperability와 stable trace event
741-764DRM 안에서 dma-buf를 통합·노출하는 방법은 `Documentation/userspace-api/dma-buf-alloc-exchange.rst`를 참조합니다.
Linux kernel tracepoint 사용법은 `Documentation/trace/tracepoints.rst`를 참조합니다. DRM subsystem의 일부 event는 GPUVis, umr 같은 tool을 깨뜨리지 않기 위해 stable uAPI로 간주됩니다.
Stable event에서는 field를 제거하거나 formatting을 바꿀 수 없습니다. 새 field 추가는 일반 uAPI 요구사항을 충족하면 가능합니다. `drivers/gpu/drm/scheduler/gpu_scheduler_trace.h`의 `uAPI trace events` kernel-doc이 stable scheduler event를 정의합니다.
Tool compatibility를 위해 허용되는 변경과 금지되는 변경입니다.
GPU scheduler가 stable uAPI로 제공하는 trace event 문서입니다.
dma-buf interoperability
========================
Please see Documentation/userspace-api/dma-buf-alloc-exchange.rst for
information on how dma-buf is integrated and exposed within DRM.
Trace events
============
See Documentation/trace/tracepoints.rst for information about using
Linux Kernel Tracepoints.
In the DRM subsystem, some events are considered stable uAPI to avoid
breaking tools (e.g.: GPUVis, umr) relying on them. Stable means that fields
cannot be removed, nor their formatting updated. Adding new fields is
possible, under the normal uAPI requirements.
Stable uAPI events
------------------
From ``drivers/gpu/drm/scheduler/gpu_scheduler_trace.h``
.. kernel-doc:: drivers/gpu/drm/scheduler/gpu_scheduler_trace.h
:doc: uAPI trace events
요약·해설
drm-uapi.rst:1-764DRM primary/render node와 authentication·lease, open-source userspace가 선행되어야 하는 ABI 정책, hot-unplug·reset·wedging recovery 계약, ioctl errno, IGT·VKMS 검증, debugfs/sysfs·vblank·dma-buf·stable trace event를 설명합니다. Udev rule·shell script·test command와 19개 kernel-doc source·selector를 원문 그대로 보존합니다.
새 userspace interface를 설계·배포할 때 확인할 주요 절입니다.