| .. _drm-client-usage-stats: | |
| ====================== | |
| DRM client usage stats | |
| ====================== | |
| DRM drivers can choose to export partly standardised text output via the | |
| `fops->show_fdinfo()` as part of the driver specific file operations registered | |
| in the `struct drm_driver` object registered with the DRM core. | |
| One purpose of this output is to enable writing as generic as practically | |
| feasible `top(1)` like userspace monitoring tools. | |
| Given the differences between various DRM drivers the specification of the | |
| output is split between common and driver specific parts. Having said that, | |
| wherever possible effort should still be made to standardise as much as | |
| possible. | |
| .. contents:: | |
| File format specification | |
| ========================= | |
| - File shall contain one key value pair per one line of text. | |
| - Colon character (`:`) must be used to delimit keys and values. | |
| - All standardised keys shall be prefixed with `drm-`. | |
| - Driver-specific keys shall be prefixed with `driver_name-`, where | |
| driver_name should ideally be the same as the `name` field in | |
| `struct drm_driver`, although this is not mandatory. | |
| - Whitespace between the delimiter and first non-whitespace character shall be | |
| ignored when parsing. | |
| - Keys are not allowed to contain whitespace characters. | |
| - Numerical key value pairs can end with optional unit string. | |
| - Data type of the value is fixed as defined in the specification. | |
| Key types | |
| --------- | |
| 1. Mandatory, fully standardised. | |
| 2. Optional, fully standardised. | |
| 3. Driver specific. | |
| Data types | |
| ---------- | |
| - <uint> - Unsigned integer without defining the maximum value. | |
| - <keystr> - String excluding any above defined reserved characters or whitespace. | |
| - <valstr> - String. | |
| Mandatory fully standardised keys | |
| --------------------------------- | |
| - drm-driver: <valstr> | |
| String shall contain the name this driver registered as via the respective | |
| `struct drm_driver` data structure. | |
| Optional fully standardised keys | |
| -------------------------------- | |
| Identification | |
| ^^^^^^^^^^^^^^ | |
| - drm-pdev: <aaaa:bb.cc.d> | |
| For PCI devices this should contain the PCI slot address of the device in | |
| question. | |
| - drm-client-id: <uint> | |
| Unique value relating to the open DRM file descriptor used to distinguish | |
| duplicated and shared file descriptors. Conceptually the value should map 1:1 | |
| to the in kernel representation of `struct drm_file` instances. | |
| Uniqueness of the value shall be either globally unique, or unique within the | |
| scope of each device, in which case `drm-pdev` shall be present as well. | |
| Userspace should make sure to not double account any usage statistics by using | |
| the above described criteria in order to associate data to individual clients. | |
| - drm-client-name: <valstr> | |
| String optionally set by userspace using DRM_IOCTL_SET_CLIENT_NAME. | |
| Utilization | |
| ^^^^^^^^^^^ | |
| - drm-engine-<keystr>: <uint> ns | |
| GPUs usually contain multiple execution engines. Each shall be given a stable | |
| and unique name (keystr), with possible values documented in the driver specific | |
| documentation. | |
| Value shall be in specified time units which the respective GPU engine spent | |
| busy executing workloads belonging to this client. | |
| Values are not required to be constantly monotonic if it makes the driver | |
| implementation easier, but are required to catch up with the previously reported | |
| larger value within a reasonable period. Upon observing a value lower than what | |
| was previously read, userspace is expected to stay with that larger previous | |
| value until a monotonic update is seen. | |
| - drm-engine-capacity-<keystr>: <uint> | |
| Engine identifier string must be the same as the one specified in the | |
| drm-engine-<keystr> tag and shall contain a greater than zero number in case the | |
| exported engine corresponds to a group of identical hardware engines. | |
| In the absence of this tag parser shall assume capacity of one. Zero capacity | |
| is not allowed. | |
| - drm-cycles-<keystr>: <uint> | |
| Engine identifier string must be the same as the one specified in the | |
| drm-engine-<keystr> tag and shall contain the number of busy cycles for the given | |
| engine. | |
| Values are not required to be constantly monotonic if it makes the driver | |
| implementation easier, but are required to catch up with the previously reported | |
| larger value within a reasonable period. Upon observing a value lower than what | |
| was previously read, userspace is expected to stay with that larger previous | |
| value until a monotonic update is seen. | |
| - drm-total-cycles-<keystr>: <uint> | |
| Engine identifier string must be the same as the one specified in the | |
| drm-cycles-<keystr> tag and shall contain the total number cycles for the given | |
| engine. | |
| This is a timestamp in GPU unspecified unit that matches the update rate | |
| of drm-cycles-<keystr>. For drivers that implement this interface, the engine | |
| utilization can be calculated entirely on the GPU clock domain, without | |
| considering the CPU sleep time between 2 samples. | |
| A driver may implement either this key or drm-maxfreq-<keystr>, but not both. | |
| - drm-maxfreq-<keystr>: <uint> [Hz|MHz|KHz] | |
| Engine identifier string must be the same as the one specified in the | |
| drm-engine-<keystr> tag and shall contain the maximum frequency for the given | |
| engine. Taken together with drm-cycles-<keystr>, this can be used to calculate | |
| percentage utilization of the engine, whereas drm-engine-<keystr> only reflects | |
| time active without considering what frequency the engine is operating as a | |
| percentage of its maximum frequency. | |
| A driver may implement either this key or drm-total-cycles-<keystr>, but not | |
| both. | |
| Memory | |
| ^^^^^^ | |
| Each possible memory type which can be used to store buffer objects by the GPU | |
| in question shall be given a stable and unique name to be used as the "<region>" | |
| string. | |
| The region name "memory" is reserved to refer to normal system memory. | |
| The value shall reflect the amount of storage currently consumed by the buffer | |
| objects belong to this client, in the respective memory region. | |
| Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB' | |
| indicating kibi- or mebi-bytes. | |
| - drm-total-<region>: <uint> [KiB|MiB] | |
| The total size of all requested buffers, including both shared and private | |
| memory. The backing store for the buffers does not need to be currently | |
| instantiated to count under this category. To avoid double-counting, if a buffer | |
| has multiple regions where it can be allocated to, the implementation should | |
| consistently select a single region for accounting purposes. | |
| - drm-shared-<region>: <uint> [KiB|MiB] | |
| The total size of buffers that are shared with another file (i.e., have more | |
| than one handle). The same requirement to avoid double-counting that applies to | |
| drm-total-<region> also applies here. | |
| - drm-resident-<region>: <uint> [KiB|MiB] | |
| The total size of buffers that are resident (i.e., have their backing store | |
| present or instantiated) in the specified region. | |
| - drm-memory-<region>: <uint> [KiB|MiB] | |
| This key is deprecated and is only printed by amdgpu; it is an alias for | |
| drm-resident-<region>. | |
| - drm-purgeable-<region>: <uint> [KiB|MiB] | |
| The total size of buffers that are resident and purgeable. | |
| For example, drivers that implement functionality similar to 'madvise' can count | |
| buffers that have instantiated backing stores but have been marked with an | |
| equivalent of MADV_DONTNEED. | |
| - drm-active-<region>: <uint> [KiB|MiB] | |
| The total size of buffers that are active on one or more engines. | |
| One practical example of this could be the presence of unsignaled fences in a | |
| GEM buffer reservation object. Therefore, the active category is a subset of the | |
| resident category. | |
| Implementation Details | |
| ====================== | |
| Drivers should use drm_show_fdinfo() in their `struct file_operations`, and | |
| implement &drm_driver.show_fdinfo if they wish to provide any stats which | |
| are not provided by drm_show_fdinfo(). But even driver specific stats should | |
| be documented above and where possible, aligned with other drivers. | |
| Driver specific implementations | |
| ------------------------------- | |
| * :ref:`i915-usage-stats` | |
| * :ref:`panfrost-usage-stats` | |
| * :ref:`panthor-usage-stats` | |
| * :ref:`xe-usage-stats` | |
| * :ref:`amdxdna-usage-stats` |