Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
129f5ea
drm: expose GEM memory accounting through Rust fdinfo
DjDeveloperr Oct 19, 2026
8bea024
drm/asahi: account G17 allocations and compact render state
DjDeveloperr Oct 19, 2026
f1d9e5c
drm/asahi: export validated G17 firmware GPU utilization
DjDeveloperr Oct 19, 2026
c61760e
drm/asahi: reclaim unused G17 render warming under queue pressure
DjDeveloperr Oct 19, 2026
d14aac5
drm/asahi: recover unused initial G17 queue IDs for compute
DjDeveloperr Oct 20, 2026
8f429c0
drm/asahi: find common addresses for G17 render pool backing
DjDeveloperr Oct 20, 2026
a5806fd
drm/asahi: wait for pending G17 compute pool releases
DjDeveloperr Oct 20, 2026
c379922
driver core: track devres node membership for direct removal
DjDeveloperr Oct 20, 2026
aa5996f
drm/asahi: reduce minimum G17 target record backing
DjDeveloperr Oct 20, 2026
13ddec8
drm/asahi: keep G17 queue identity contention from failing clients
DjDeveloperr Oct 22, 2026
f4feef8
drm/asahi: order G17 queue owner changes after scheduler releases
DjDeveloperr Oct 22, 2026
2da55b0
drm/asahi: wait for exhausted G17 render resources and name them
DjDeveloperr Oct 22, 2026
5b16bbd
drm/asahi: keep G17 render capacity waits from stopping the runtime
DjDeveloperr Oct 22, 2026
0ce71e3
drm/asahi: wait for G17 contexts of closing queues at queue creation
DjDeveloperr Oct 22, 2026
ffca576
drm/asahi: keep G17 render kick ring storage for the life of the device
DjDeveloperr Oct 22, 2026
9c4ffd7
drm/asahi: bound G17 publication waits by one deadline and keep them …
DjDeveloperr Oct 22, 2026
98a5ccb
drm/asahi: rerun the G17 event pass for completions missed while a pa…
DjDeveloperr Oct 22, 2026
dfef788
drm/asahi: wait for a borrowed G17 render pair to return, not 200 us
DjDeveloperr Oct 22, 2026
3082345
drm/asahi: queue dependent G17 renders behind their predecessor's pair
DjDeveloperr Oct 22, 2026
41ef5e9
drm/asahi: reuse G17 compute timestamp pages within a context
DjDeveloperr Oct 22, 2026
46a16d9
drm/asahi: publish dependency-free G17 compute commands from the subm…
DjDeveloperr Oct 22, 2026
639fef4
drm/asahi: publish G17 compute from the submit ioctl up to four comma…
DjDeveloperr Oct 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions Documentation/ABI/testing/sysfs-driver-asahi
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
What: /sys/devices/platform/.../*.gpu/agx_stats
Date: October 2026
Contact: Aurora Silicon developers
Description:
Read-only, per-device firmware GPU utilization on T8140 G17P.
With asahi.stats_export=0, the file reports unsupported.
The default value 1 enables the version 2 export described here.
Earlier GPU generations use the separate legacy agx_stats format.
Version 2 is a whitespace-delimited key/value format. Readers
must check the version and load_valid before using percentages.

version: 2
source: firmware
load_valid: 1 if the current utilization is available, else 0
busy_percent: firmware aggregate utilization, percent (0..100)
util1..util3: firmware engine percentages (0..100); engine labels
are not assigned without independent validation
util4: same aggregate as busy_percent; do not sum engine values
gpu_power_known: whether a timestamped power state was received
gpu_powered: 0 when firmware reports the GPU powered off, else 1
samples: accepted primary utilization reports since probe
sample_received_ns: host CLOCK_MONOTONIC receive timestamp
sample_age_ns: time since the retained utilization report
sample_timestamp_ticks: 64-bit firmware utilization timestamp
power_timestamp_ticks: newest secondary power-state timestamp
clock_hz: 24000000 (timestamp and residency ticks)
powered_ticks: completed powered intervals, accumulated from
firmware power-off records since probe
unpowered_ticks: completed unpowered intervals, accumulated from
firmware power-on records since probe
invalid_samples: malformed utilization/power records rejected

A timestamped power-off witness overrides retained utilization
with zero. After wake, an old utilization report is unavailable
until a report for the new interval arrives. Device loss or
shutdown invalidates load until a new device is probed. Receive timestamps
do not order events across firmware rings: firmware timestamps
determine which state is newer. Suspend can separate the host
and firmware clocks; do not subtract values from those domains.

Power residency is not GPU busy time. Residency counters omit
the currently open power interval and saturate at U64_MAX.
Neither these counters nor the percentages are per-client DRM
engine execution time. No per-client execution counter is
synthesized from queue admission, wall time or job spans.

Reading debugfs asahi-g17/statistics requests two seconds of full
raw-payload capture, including undecoded record kinds. Repeat
reads to keep diagnostic capture active. It is disabled by
default and is not needed for normal utilization reporting.
Trace records and uncaptured statistics only read required words.
Captured counts exclude records outside the capture window. That diagnostic format is not a
stable userspace ABI. Optional telemetry registration failure
does not prevent GPU initialization and is logged by the driver.
3 changes: 3 additions & 0 deletions Documentation/ABI/testing/sysfs-driver-asahi-agx-stats
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ What: /sys/class/drm/card*/device/agx_stats
Date: October 2026
Contact: Asahi Linux GPU driver maintainers
Description:
Legacy GPU format. For T8140 G17P, see sysfs-driver-asahi
for the version 2 format and power-state validity rules.

Read-only dump of the AGX firmware statistics decoded by the
drm/asahi driver. The driver already polls the firmware statistics
ring (see `drivers/gpu/drm/asahi/channel.rs::StatsChannel::poll`,
Expand Down
2 changes: 2 additions & 0 deletions drivers/base/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ typedef void (*dr_node_free_t)(struct devres_node *node);

struct devres_node {
struct list_head entry;
/* Device-list membership, cleared under devres_lock before detachment. */
struct device *owner;
dr_node_release_t release;
dr_node_free_t free_node;
const char *name;
Expand Down
29 changes: 18 additions & 11 deletions drivers/base/devres.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ void devres_node_init(struct devres_node *node,
dr_node_free_t free_node)
{
INIT_LIST_HEAD(&node->entry);
WRITE_ONCE(node->owner, NULL);
node->release = release;
node->free_node = free_node;
}
Expand Down Expand Up @@ -156,6 +157,7 @@ static void add_dr(struct device *dev, struct devres_node *node)
devres_log(dev, node, "ADD");
BUG_ON(!list_empty(&node->entry));
list_add_tail(&node->entry, &dev->devres_head);
WRITE_ONCE(node->owner, dev);
}

static void replace_dr(struct device *dev,
Expand All @@ -164,6 +166,8 @@ static void replace_dr(struct device *dev,
devres_log(dev, old, "REPLACE");
BUG_ON(!list_empty(&new->entry));
list_replace(&old->entry, &new->entry);
WRITE_ONCE(old->owner, NULL);
WRITE_ONCE(new->owner, dev);
}

/**
Expand Down Expand Up @@ -367,18 +371,14 @@ EXPORT_SYMBOL_GPL(devres_get);

bool devres_node_remove(struct device *dev, struct devres_node *node)
{
struct devres_node *__node;

guard(spinlock_irqsave)(&dev->devres_lock);
list_for_each_entry_reverse(__node, &dev->devres_head, entry) {
if (__node == node) {
list_del_init(&node->entry);
devres_log(dev, node, "REM");
return true;
}
}

return false;
/* A release-all/group pass may own a detached node on its private list. */
if (READ_ONCE(node->owner) != dev)
return false;
list_del_init(&node->entry);
WRITE_ONCE(node->owner, NULL);
devres_log(dev, node, "REM");
return true;
}

/**
Expand All @@ -405,6 +405,7 @@ void *devres_remove(struct device *dev, dr_release_t release,
dr = find_dr(dev, release, match, match_data);
if (dr) {
list_del_init(&dr->node.entry);
WRITE_ONCE(dr->node.owner, NULL);
devres_log(dev, &dr->node, "REM");
return dr->data;
}
Expand Down Expand Up @@ -500,6 +501,7 @@ static int remove_nodes(struct device *dev,
if (&node->entry == first)
first = first->next;
list_move_tail(&node->entry, todo);
WRITE_ONCE(node->owner, NULL);
cnt++;
}
}
Expand Down Expand Up @@ -530,7 +532,9 @@ static int remove_nodes(struct device *dev,
* nodes are always before both.
*/
list_move_tail(&grp->node[0].entry, todo);
WRITE_ONCE(grp->node[0].owner, NULL);
list_del_init(&grp->node[1].entry);
WRITE_ONCE(grp->node[1].owner, NULL);
}
}

Expand Down Expand Up @@ -685,7 +689,9 @@ void devres_remove_group(struct device *dev, void *id)
grp = find_group(dev, id);
if (grp) {
list_del_init(&grp->node[0].entry);
WRITE_ONCE(grp->node[0].owner, NULL);
list_del_init(&grp->node[1].entry);
WRITE_ONCE(grp->node[1].owner, NULL);
devres_log(dev, &grp->node[0], "REM");
} else
WARN_ON(1);
Expand Down Expand Up @@ -849,6 +855,7 @@ static struct devres_action *remove_action(struct device *dev,
return ERR_PTR(-ENOENT);

list_del_init(&dr->node.entry);
WRITE_ONCE(dr->node.owner, NULL);
devres_log(dev, &dr->node, "REM");

return dr;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/asahi/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0

obj-$(CONFIG_DRM_ASAHI) += asahi.o
asahi-y := asahi_core.o sysfs.o
asahi-y := asahi_core.o sysfs.o asahi_telemetry.o
Loading
Loading