| 1 | |
| 2 |
|
| 3 | ======================
|
| 4 | DRM client usage stats
|
| 5 | ======================
|
| 6 |
|
| 7 | DRM drivers can choose to export partly standardised text output via the
|
| 8 | `fops->show_fdinfo()` as part of the driver specific file operations registered
|
| 9 | in the `struct drm_driver` object registered with the DRM core.
|
| 10 |
|
| 11 | One purpose of this output is to enable writing as generic as practically
|
| 12 | feasible `top(1)` like userspace monitoring tools.
|
| 13 |
|
| 14 | Given the differences between various DRM drivers the specification of the
|
| 15 | output is split between common and driver specific parts. Having said that,
|
| 16 | wherever possible effort should still be made to standardise as much as
|
| 17 | possible.
|
| 18 |
|
| 19 | .. contents::
|
| 20 |
|
| 21 | File format specification
|
| 22 | =========================
|
| 23 |
|
| 24 | - File shall contain one key value pair per one line of text.
|
| 25 | - Colon character (`:`) must be used to delimit keys and values.
|
| 26 | - All standardised keys shall be prefixed with `drm-`.
|
| 27 | - Driver-specific keys shall be prefixed with `driver_name-`, where
|
| 28 | driver_name should ideally be the same as the `name` field in
|
| 29 | `struct drm_driver`, although this is not mandatory.
|
| 30 | - Whitespace between the delimiter and first non-whitespace character shall be
|
| 31 | ignored when parsing.
|
| 32 | - Keys are not allowed to contain whitespace characters.
|
| 33 | - Numerical key value pairs can end with optional unit string.
|
| 34 | - Data type of the value is fixed as defined in the specification.
|
| 35 |
|
| 36 | Key types
|
| 37 | ---------
|
| 38 |
|
| 39 | 1. Mandatory, fully standardised.
|
| 40 | 2. Optional, fully standardised.
|
| 41 | 3. Driver specific.
|
| 42 |
|
| 43 | Data types
|
| 44 | ----------
|
| 45 |
|
| 46 | - <uint> - Unsigned integer without defining the maximum value.
|
| 47 | - <keystr> - String excluding any above defined reserved characters or whitespace.
|
| 48 | - <valstr> - String.
|
| 49 |
|
| 50 | Mandatory fully standardised keys
|
| 51 | ---------------------------------
|
| 52 |
|
| 53 | - drm-driver: <valstr>
|
| 54 |
|
| 55 | String shall contain the name this driver registered as via the respective
|
| 56 | `struct drm_driver` data structure.
|
| 57 |
|
| 58 | Optional fully standardised keys
|
| 59 | --------------------------------
|
| 60 |
|
| 61 | Identification
|
| 62 | ^^^^^^^^^^^^^^
|
| 63 |
|
| 64 | - drm-pdev: <aaaa:bb.cc.d>
|
| 65 |
|
| 66 | For PCI devices this should contain the PCI slot address of the device in
|
| 67 | question.
|
| 68 |
|
| 69 | - drm-client-id: <uint>
|
| 70 |
|
| 71 | Unique value relating to the open DRM file descriptor used to distinguish
|
| 72 | duplicated and shared file descriptors. Conceptually the value should map 1:1
|
| 73 | to the in kernel representation of `struct drm_file` instances.
|
| 74 |
|
| 75 | Uniqueness of the value shall be either globally unique, or unique within the
|
| 76 | scope of each device, in which case `drm-pdev` shall be present as well.
|
| 77 |
|
| 78 | Userspace should make sure to not double account any usage statistics by using
|
| 79 | the above described criteria in order to associate data to individual clients.
|
| 80 |
|
| 81 | - drm-client-name: <valstr>
|
| 82 |
|
| 83 | String optionally set by userspace using DRM_IOCTL_SET_CLIENT_NAME.
|
| 84 |
|
| 85 |
|
| 86 | Utilization
|
| 87 | ^^^^^^^^^^^
|
| 88 |
|
| 89 | - drm-engine-<keystr>: <uint> ns
|
| 90 |
|
| 91 | GPUs usually contain multiple execution engines. Each shall be given a stable
|
| 92 | and unique name (keystr), with possible values documented in the driver specific
|
| 93 | documentation.
|
| 94 |
|
| 95 | Value shall be in specified time units which the respective GPU engine spent
|
| 96 | busy executing workloads belonging to this client.
|
| 97 |
|
| 98 | Values are not required to be constantly monotonic if it makes the driver
|
| 99 | implementation easier, but are required to catch up with the previously reported
|
| 100 | larger value within a reasonable period. Upon observing a value lower than what
|
| 101 | was previously read, userspace is expected to stay with that larger previous
|
| 102 | value until a monotonic update is seen.
|
| 103 |
|
| 104 | - drm-engine-capacity-<keystr>: <uint>
|
| 105 |
|
| 106 | Engine identifier string must be the same as the one specified in the
|
| 107 | drm-engine-<keystr> tag and shall contain a greater than zero number in case the
|
| 108 | exported engine corresponds to a group of identical hardware engines.
|
| 109 |
|
| 110 | In the absence of this tag parser shall assume capacity of one. Zero capacity
|
| 111 | is not allowed.
|
| 112 |
|
| 113 | - drm-cycles-<keystr>: <uint>
|
| 114 |
|
| 115 | Engine identifier string must be the same as the one specified in the
|
| 116 | drm-engine-<keystr> tag and shall contain the number of busy cycles for the given
|
| 117 | engine.
|
| 118 |
|
| 119 | Values are not required to be constantly monotonic if it makes the driver
|
| 120 | implementation easier, but are required to catch up with the previously reported
|
| 121 | larger value within a reasonable period. Upon observing a value lower than what
|
| 122 | was previously read, userspace is expected to stay with that larger previous
|
| 123 | value until a monotonic update is seen.
|
| 124 |
|
| 125 | - drm-total-cycles-<keystr>: <uint>
|
| 126 |
|
| 127 | Engine identifier string must be the same as the one specified in the
|
| 128 | drm-cycles-<keystr> tag and shall contain the total number cycles for the given
|
| 129 | engine.
|
| 130 |
|
| 131 | This is a timestamp in GPU unspecified unit that matches the update rate
|
| 132 | of drm-cycles-<keystr>. For drivers that implement this interface, the engine
|
| 133 | utilization can be calculated entirely on the GPU clock domain, without
|
| 134 | considering the CPU sleep time between 2 samples.
|
| 135 |
|
| 136 | A driver may implement either this key or drm-maxfreq-<keystr>, but not both.
|
| 137 |
|
| 138 | - drm-maxfreq-<keystr>: <uint> [Hz|MHz|KHz]
|
| 139 |
|
| 140 | Engine identifier string must be the same as the one specified in the
|
| 141 | drm-engine-<keystr> tag and shall contain the maximum frequency for the given
|
| 142 | engine. Taken together with drm-cycles-<keystr>, this can be used to calculate
|
| 143 | percentage utilization of the engine, whereas drm-engine-<keystr> only reflects
|
| 144 | time active without considering what frequency the engine is operating as a
|
| 145 | percentage of its maximum frequency.
|
| 146 |
|
| 147 | A driver may implement either this key or drm-total-cycles-<keystr>, but not
|
| 148 | both.
|
| 149 |
|
| 150 | Memory
|
| 151 | ^^^^^^
|
| 152 |
|
| 153 | Each possible memory type which can be used to store buffer objects by the GPU
|
| 154 | in question shall be given a stable and unique name to be used as the "<region>"
|
| 155 | string.
|
| 156 |
|
| 157 | The region name "memory" is reserved to refer to normal system memory.
|
| 158 |
|
| 159 | The value shall reflect the amount of storage currently consumed by the buffer
|
| 160 | objects belong to this client, in the respective memory region.
|
| 161 |
|
| 162 | Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB'
|
| 163 | indicating kibi- or mebi-bytes.
|
| 164 |
|
| 165 | - drm-total-<region>: <uint> [KiB|MiB]
|
| 166 |
|
| 167 | The total size of all requested buffers, including both shared and private
|
| 168 | memory. The backing store for the buffers does not need to be currently
|
| 169 | instantiated to count under this category. To avoid double-counting, if a buffer
|
| 170 | has multiple regions where it can be allocated to, the implementation should
|
| 171 | consistently select a single region for accounting purposes.
|
| 172 |
|
| 173 | - drm-shared-<region>: <uint> [KiB|MiB]
|
| 174 |
|
| 175 | The total size of buffers that are shared with another file (i.e., have more
|
| 176 | than one handle). The same requirement to avoid double-counting that applies to
|
| 177 | drm-total-<region> also applies here.
|
| 178 |
|
| 179 | - drm-resident-<region>: <uint> [KiB|MiB]
|
| 180 |
|
| 181 | The total size of buffers that are resident (i.e., have their backing store
|
| 182 | present or instantiated) in the specified region.
|
| 183 |
|
| 184 | - drm-memory-<region>: <uint> [KiB|MiB]
|
| 185 |
|
| 186 | This key is deprecated and is only printed by amdgpu; it is an alias for
|
| 187 | drm-resident-<region>.
|
| 188 |
|
| 189 | - drm-purgeable-<region>: <uint> [KiB|MiB]
|
| 190 |
|
| 191 | The total size of buffers that are resident and purgeable.
|
| 192 |
|
| 193 | For example, drivers that implement functionality similar to 'madvise' can count
|
| 194 | buffers that have instantiated backing stores but have been marked with an
|
| 195 | equivalent of MADV_DONTNEED.
|
| 196 |
|
| 197 | - drm-active-<region>: <uint> [KiB|MiB]
|
| 198 |
|
| 199 | The total size of buffers that are active on one or more engines.
|
| 200 |
|
| 201 | One practical example of this could be the presence of unsignaled fences in a
|
| 202 | GEM buffer reservation object. Therefore, the active category is a subset of the
|
| 203 | resident category.
|
| 204 |
|
| 205 | Implementation Details
|
| 206 | ======================
|
| 207 |
|
| 208 | Drivers should use drm_show_fdinfo() in their `struct file_operations`, and
|
| 209 | implement &drm_driver.show_fdinfo if they wish to provide any stats which
|
| 210 | are not provided by drm_show_fdinfo(). But even driver specific stats should
|
| 211 | be documented above and where possible, aligned with other drivers.
|
| 212 |
|
| 213 | Driver specific implementations
|
| 214 | -------------------------------
|
| 215 |
|
| 216 | * :ref:`i915-usage-stats`
|
| 217 | * :ref:`panfrost-usage-stats`
|
| 218 | * :ref:`panthor-usage-stats`
|
| 219 | * :ref:`xe-usage-stats`
|
| 220 | * :ref:`amdxdna-usage-stats`
|