diff options
| author | Tim Chen <tim.c.chen@linux.intel.com> | 2026-09-21 17:37:22 -0700 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2026-09-22 10:49:53 +0200 |
| commit | 0d6526f82c3cdefcca47f73f5fc08dc6f335eac6 (patch) | |
| tree | 176dc2d685debcfb082c151ee94f2425ac96b364 /Documentation/gpu/drm-usage-stats.rst | |
| download | linux-stable-0d6526f82c3cdefcca47f73f5fc08dc6f335eac6.tar.gz linux-stable-0d6526f82c3cdefcca47f73f5fc08dc6f335eac6.zip | |
sched/cache: Keep nr_pref_llc_running in the runnable domain, to fix LLC mis-scheduling buggrafted
alb_break_llc() decides whether to break LLC preference during active
load balance. It does so by testing that every runnable fair task on the
source rq prefers its LLC:
env->src_rq->nr_pref_llc_running == env->src_rq->cfs.h_nr_runnable
But the two counters cover different sets. nr_pref_llc_running is updated
in account_llc_enqueue()/account_llc_dequeue(), next to cfs_rq->nr_queued,
so it follows queued tasks. h_nr_runnable is updated in set_delayed()/
clear_delayed() and drops delay-dequeued tasks.
So under DELAY_DEQUEUE, a preferring task that goes to sleep stays counted
in nr_pref_llc_running while h_nr_runnable falls. The equality then breaks,
alb_break_llc() returns false, and active balance is free to pull a task
off its preferred LLC. Active balance only moves runnable tasks, and this
is the only LLC check it consults: once the stopper runs, LBF_ACTIVE_LB
skips the per-task test in can_migrate_task(). The runnable set is the one
we want.
Fix it on the counter side. A task should be counted in
nr_pref_llc_running exactly while it is both queued on its preferred LLC
(pref_llc_queued) and runnable (!sched_delayed). Define that membership
once in task_pref_llc_runnable(), and adjust the counter only through
pref_llc_running_inc()/pref_llc_running_dec() from the four sites that
change either input: account_llc_enqueue(), account_llc_dequeue(),
set_delayed() and clear_delayed(). Gating every update on the same
predicate keeps the delay, wake and dequeue paths from double-counting
or underflowing; see the comments at those sites for the ordering.
nr_llc_running and sd->llc_counts are not touched and stay on queued
semantics.
Fixes: 714059f79ff0 ("sched/cache: Handle moving single tasks to/from their preferred LLC")
Closes: https://lore.kernel.org/lkml/20260827135000.735138-1-zhanxusheng@xiaomi.com/
Reported-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Suggested-by: Chen Yu <yu.c.chen@intel.com>
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Kayra Cizmeci <kayracizmeci@gmail.com>
Cc: <stable@kernel.org> # v7.2.x
Link: https://patch.msgid.link/06af61afedac32e6477f57feb4d658f6c411c3af.1790035273.git.tim.c.chen@linux.intel.com
Diffstat (limited to 'Documentation/gpu/drm-usage-stats.rst')
| -rw-r--r-- | Documentation/gpu/drm-usage-stats.rst | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/Documentation/gpu/drm-usage-stats.rst b/Documentation/gpu/drm-usage-stats.rst new file mode 100644 index 000000000..70b7cfcc1 --- /dev/null +++ b/Documentation/gpu/drm-usage-stats.rst @@ -0,0 +1,220 @@ +.. _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` |
