요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. _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.
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`
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
DRM client 사용량 통계의 목적
1-18DRM driver는 DRM core에 등록한 `struct drm_driver` 객체의 driver-specific file operation 일부로 `fops->show_fdinfo()`를 제공하여, 부분적으로 표준화된 text 출력을 선택적으로 내보낼 수 있습니다.
이 출력의 목적 중 하나는 가능한 한 여러 DRM driver에서 공통으로 사용할 수 있는 `top(1)` 형태의 userspace monitoring tool을 작성할 수 있게 하는 것입니다.
DRM driver마다 기능과 계수 방식이 다르므로 출력 명세는 공통 부분과 driver-specific 부분으로 나뉩니다. 그렇더라도 공통 의미를 정의할 수 있는 항목은 최대한 표준화해야 합니다.
Driver가 수집한 client별 사용량이 userspace monitor에 전달되는 흐름입니다.
.. _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.
파일 형식, key 종류와 data type
19-47파일의 각 text line에는 key-value pair를 정확히 하나만 기록해야 하며 key와 value는 colon 문자 `:`로 구분합니다. 모든 표준 key에는 `drm-` prefix를 붙이고, driver-specific key에는 `driver_name-` prefix를 붙입니다.
여기서 `driver_name`은 필수 조건은 아니지만 가능하면 `struct drm_driver`의 `name` field와 같아야 합니다. Parser는 delimiter와 첫 non-whitespace 문자 사이의 whitespace를 무시해야 하며 key 자체에는 whitespace를 넣을 수 없습니다.
숫자 key-value pair 뒤에는 선택적인 unit string을 붙일 수 있습니다. 각 value의 data type은 이 명세가 정의한 형식으로 고정됩니다.
Parser와 producer가 동일하게 따라야 하는 line·key 규칙입니다.
Key는 세 종류로 구분합니다. 첫째는 mandatory·fully standardised key, 둘째는 optional·fully standardised key, 셋째는 driver-specific key입니다.
사용량 통계 key가 사용할 수 있는 value 형식입니다.
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.
필수 driver key와 client 식별
48-83완전히 표준화된 필수 key는 `drm-driver: <valstr>`입니다. Value에는 해당 driver가 `struct drm_driver` data structure를 통해 등록한 이름을 기록해야 합니다.
선택적 식별 key `drm-pdev: <aaaa:bb.cc.d>`는 PCI device의 slot address를 나타냅니다. `drm-client-id: <uint>`는 열린 DRM file descriptor와 연관된 고유값으로, duplicate 또는 shared file descriptor를 구분합니다. 개념적으로 이 값은 kernel 내부의 `struct drm_file` instance와 1:1로 대응해야 합니다.
Client ID는 전역에서 고유하거나 각 device 범위에서 고유해야 합니다. Device 범위에서만 고유하다면 `drm-pdev`도 반드시 제공해야 합니다. Userspace는 이 두 기준으로 data를 individual client에 연결하여 동일 사용량을 중복 계상하지 않아야 합니다.
`drm-client-name: <valstr>`은 userspace가 `DRM_IOCTL_SET_CLIENT_NAME`으로 선택적으로 지정한 이름을 담습니다.
중복 descriptor와 device별 client를 올바르게 묶기 위한 표준 key입니다.
Client ID의 고유성 범위에 따라 userspace가 선택할 식별 기준입니다.
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.
Engine 사용 시간, capacity, cycle과 frequency
84-147GPU에는 보통 여러 execution engine이 있습니다. 각 engine에는 안정적이고 고유한 `<keystr>` 이름을 부여하고 가능한 값은 driver-specific documentation에 기록해야 합니다.
`drm-engine-<keystr>: <uint> ns`는 이 client의 workload를 실행하느라 해당 GPU engine이 busy 상태였던 시간을 지정된 time unit으로 나타냅니다.
Driver 구현을 단순하게 하기 위해 값이 항상 단조 증가할 필요는 없습니다. 다만 합리적인 시간 안에 이전에 보고한 더 큰 값까지 따라잡아야 합니다. Userspace가 이전보다 작은 값을 읽으면 다시 단조 증가하는 update가 나타날 때까지 이전의 더 큰 값을 유지해야 합니다.
`drm-engine-capacity-<keystr>: <uint>`의 engine identifier는 `drm-engine-<keystr>`와 같아야 합니다. Export된 engine이 동일한 hardware engine 여러 개의 group이면 0보다 큰 개수를 기록합니다. 이 tag가 없으면 parser는 capacity를 1로 간주하며 0은 허용하지 않습니다.
`drm-cycles-<keystr>: <uint>`도 같은 engine identifier를 사용하며 해당 engine의 busy cycle 수를 담습니다. 이 값에도 `drm-engine-*`과 동일한 일시적 비단조성 및 catch-up 규칙이 적용됩니다.
`drm-total-cycles-<keystr>: <uint>`는 `drm-cycles-<keystr>`와 같은 engine identifier를 사용하고 해당 engine의 total cycle 수를 담습니다. 이는 `drm-cycles-*`와 같은 update rate를 갖는 GPU 고유 unit의 timestamp이므로, 두 sample 사이 CPU sleep time을 고려하지 않고 GPU clock domain만으로 engine utilization을 계산할 수 있습니다.
`drm-maxfreq-<keystr>: <uint> [Hz|MHz|KHz]`는 `drm-engine-<keystr>`와 같은 identifier를 사용하고 engine의 maximum frequency를 나타냅니다. `drm-cycles-*`와 함께 사용하면 maximum frequency 대비 percentage utilization을 계산할 수 있습니다. 반면 `drm-engine-*`은 maximum frequency 대비 동작 비율을 고려하지 않고 active time만 나타냅니다.
Driver는 `drm-total-cycles-<keystr>`와 `drm-maxfreq-<keystr>` 중 하나만 구현할 수 있으며 둘을 동시에 구현하면 안 됩니다.
Engine별 key의 단위·식별자·기본값을 정리합니다.
Driver가 일시적으로 더 작은 누적값을 보고할 때 userspace가 적용할 규칙입니다.
Driver는 두 clock-domain 보조 key 가운데 하나만 제공합니다.
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 region별 buffer 사용량
148-202GPU가 buffer object를 저장할 수 있는 각 memory type에는 `<region>` string으로 사용할 안정적이고 고유한 이름을 부여해야 합니다. Region 이름 `memory`는 일반 system memory를 가리키도록 예약되어 있습니다.
각 값은 이 client의 buffer object가 해당 memory region에서 현재 소비하는 storage 양을 반영해야 합니다. 기본 unit은 byte이며 선택적으로 `KiB` 또는 `MiB`를 붙여 kibibyte나 mebibyte를 나타낼 수 있습니다.
`drm-total-<region>: <uint> [KiB|MiB]`는 shared memory와 private memory를 모두 포함한 요청 buffer 전체 크기입니다. Backing store가 아직 실제로 만들어지지 않았어도 이 category에 포함합니다. Buffer를 여러 region에 배치할 수 있다면 이중 계상을 피하도록 구현이 일관되게 region 하나만 선택해야 합니다.
`drm-shared-<region>: <uint> [KiB|MiB]`는 다른 file과 공유되어 handle이 둘 이상인 buffer의 전체 크기입니다. `drm-total-*`과 동일한 단일 region 선택 규칙을 따라야 합니다.
`drm-resident-<region>: <uint> [KiB|MiB]`는 지정된 region에 backing store가 존재하거나 instantiate된 resident buffer의 전체 크기입니다.
`drm-memory-<region>: <uint> [KiB|MiB]`는 deprecated key이며 amdgpu만 출력합니다. 이는 `drm-resident-<region>`의 alias입니다.
`drm-purgeable-<region>: <uint> [KiB|MiB]`는 resident이면서 purge 가능한 buffer 전체 크기입니다. 예를 들어 `madvise`와 비슷한 기능을 구현한 driver는 backing store가 만들어졌지만 `MADV_DONTNEED`에 해당하는 표시가 붙은 buffer를 여기에 계상할 수 있습니다.
`drm-active-<region>: <uint> [KiB|MiB]`는 하나 이상의 engine에서 active인 buffer 전체 크기입니다. GEM buffer reservation object에 unsignaled fence가 있는 경우가 한 예이며, active category는 resident category의 subset입니다.
각 category가 포함하는 buffer와 관계를 정리합니다.
동일 buffer가 각 key에 포함되는 대표적인 관계입니다.
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.
Driver 구현 API와 개별 명세
203-217Driver는 `struct file_operations`에서 `drm_show_fdinfo()`를 사용해야 합니다. `drm_show_fdinfo()`가 제공하지 않는 통계를 내보내려면 `&drm_driver.show_fdinfo`를 구현합니다.
Driver-specific 통계도 위 명세에 문서화해야 하며, 가능한 경우 다른 driver와 key 이름 및 의미를 맞춰야 합니다.
개별 구현 명세는 `i915-usage-stats`, `panfrost-usage-stats`, `panthor-usage-stats`, `xe-usage-stats` 참조에서 확인할 수 있습니다.
DRM core helper와 driver callback의 역할입니다.
문서가 연결하는 네 개의 구현별 reference입니다.
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`
요약·해설
drm-usage-stats.rst:1-217DRM driver가 `fdinfo`로 client별 engine utilization과 memory consumption을 내보내는 text ABI를 정의합니다. File format, mandatory·optional key, client 식별과 중복 계상 방지, 일시적인 비단조 counter 처리, GPU clock 기반 utilization, memory region category와 driver 구현 API를 다룹니다.
Monitoring tool이 통계를 안전하게 해석하기 위한 핵심 순서입니다.