Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
4b7aa80
drm/asahi: sync the G17 driver with aurora-silicon at d3cf19be
DjDeveloperr Oct 25, 2026
1e95ba3
drm/asahi: publish bound G17 compute work without the admission passes
DjDeveloperr Oct 23, 2026
d50ae67
drm/asahi: wake G17 render publication when its pair is returned
DjDeveloperr Oct 23, 2026
99a80c8
drm/asahi: clear each G17 compute descriptor only once
DjDeveloperr Oct 23, 2026
bbfd3c3
drm/asahi: retain compute pool backing through pending channel admission
DjDeveloperr Oct 23, 2026
cf38f6a
dma-buf: stop polling an array after its first pending member
DjDeveloperr Oct 23, 2026
403c3fe
drm/asahi: avoid unbound compute inline attempts on compute-only queues
DjDeveloperr Oct 23, 2026
e17b520
drm/asahi: preserve low-pressure compute inline probes
DjDeveloperr Oct 23, 2026
057073a
drm/asahi: submit same-VM compute input waits through firmware
DjDeveloperr Oct 24, 2026
734eace
drm/asahi: treat a firmware source as complete once its retirement is…
DjDeveloperr Oct 24, 2026
072782a
drm/asahi: publish G17 commands from the ioctl at any queue depth
DjDeveloperr Oct 24, 2026
7c1b71c
drm/asahi: map G17 compute descriptors cached for the firmware
DjDeveloperr Oct 24, 2026
501f3f8
drm/asahi: size the G17 compute QID budget by open logical queues
DjDeveloperr Oct 24, 2026
d8ef9cd
drm/asahi: order same-VM render attachment overlaps in firmware
DjDeveloperr Oct 24, 2026
04f3145
drm/asahi: map G17 compute command records cached for the firmware
DjDeveloperr Oct 24, 2026
a2c5a17
drm/asahi: stop the G17 compute completion scan once every record is …
DjDeveloperr Oct 24, 2026
8525488
drm/asahi: publish G17 compute into a bound queue without the device …
DjDeveloperr Oct 24, 2026
9fbb8de
drm/asahi: send a G17 compute queue configuration only when it changes
DjDeveloperr Oct 24, 2026
f6055a5
drm/asahi: add G17 resource wait domains and use them for queue creation
DjDeveloperr Oct 24, 2026
ff77836
drm/asahi: wait for G17 compute capacity on the release that frees it
DjDeveloperr Oct 24, 2026
ccbcd07
drm/asahi: wait for a G17 compute source only through its completion …
DjDeveloperr Oct 24, 2026
d7859c4
drm/asahi: add G17 command lifecycle tracepoints
DjDeveloperr Oct 24, 2026
0a64e52
drm/asahi: ring the G17 compute pipe doorbell for every publication
DjDeveloperr Oct 24, 2026
d0e59c3
drm/asahi: map the G17 compute queue graph cached for the firmware
DjDeveloperr Oct 24, 2026
660db57
drm/asahi: wait for G17 render capacity on the release that frees it
DjDeveloperr Oct 24, 2026
1508e67
drm/asahi: give the G17 render scheduler the pair's depth as credits
DjDeveloperr Oct 24, 2026
2a5dc61
drm/asahi: keep a G17 render free list registered while the firmware …
DjDeveloperr Oct 24, 2026
625cddd
drm/asahi: take the G17 device mutex less often to publish a render
DjDeveloperr Oct 24, 2026
1b16ae1
drm/asahi: publish a G17 render into its pair without the device mutex
DjDeveloperr Oct 24, 2026
b64d0fa
drm/asahi: lend a G17 render pair without the identity check first
DjDeveloperr Oct 24, 2026
f720d9a
drm/asahi: wait for G17 render admission before run_job
DjDeveloperr Oct 24, 2026
a20f04d
drm/asahi: trace the G17 core power state at each work doorbell
DjDeveloperr Oct 24, 2026
f092552
drm/asahi: trace G17 host-to-firmware messages
DjDeveloperr Oct 24, 2026
aefc76a
drm/asahi: maintain cumulative completion scopes without repeated fen…
DjDeveloperr Oct 24, 2026
e12ec29
drm/asahi: test G17 queue budgets with firmware-reserved identities
DjDeveloperr Oct 24, 2026
dcbf012
drm/asahi: size cached compute records for every native wait
DjDeveloperr Oct 24, 2026
26a1486
drm/asahi: index pending compute completion identities before reading…
DjDeveloperr Oct 24, 2026
54d5081
drm/asahi: retain a deep working set of validated GPU page ranges
DjDeveloperr Oct 24, 2026
56d85b5
drm/asahi: avoid locking pending private completion fences
DjDeveloperr Oct 24, 2026
009c101
drm/asahi: give G17 firmware restarts time to drain long work
DjDeveloperr Oct 25, 2026
6d1ae0d
drm/asahi: fail commands a GPU restart interrupted instead of complet…
DjDeveloperr Oct 25, 2026
8f82617
drm/asahi: stop the G17 device on a watchdog storm only without progress
DjDeveloperr Oct 25, 2026
e1812c1
drm/asahi: scan only the G17 compute completion records written since…
DjDeveloperr Oct 25, 2026
38935ee
drm/asahi: release pruned G17 frontier entries after the ioctl publishes
DjDeveloperr Oct 25, 2026
06c3e94
drm/asahi: publish both G17 render QoS owners in one pass
DjDeveloperr Oct 25, 2026
46b125c
drm/asahi: stop copying G17 fragment registers to the unused client page
DjDeveloperr Oct 25, 2026
6b652b2
drm/asahi: read the G17 render work rings once per direct publication
DjDeveloperr Oct 25, 2026
f68808a
drm/asahi: request the G17 tiling descriptor slot before preparing a …
DjDeveloperr Oct 25, 2026
0eb9a8f
drm/asahi: store G17 register arrays without an intermediate copy
DjDeveloperr Oct 25, 2026
1059235
drm/asahi: also request the G17 queue configuration records early
DjDeveloperr Oct 25, 2026
39ccfb2
drm/asahi: scan only render pool slots for G17 free-list leases
DjDeveloperr Oct 25, 2026
13ce975
drm/asahi: omit G17 render queue configurations that only reload the …
DjDeveloperr Oct 25, 2026
5d7f4a7
drm/asahi: keep one CPU mapping per G17 timestamp buffer
DjDeveloperr Oct 25, 2026
1a3fd7f
drm/asahi: withhold G17 compute doorbells behind two unretired commands
DjDeveloperr Oct 25, 2026
26ee6b9
drm/asahi: drop G17 compute doorbells that another doorbell announced
DjDeveloperr Oct 25, 2026
118c3b4
drm/asahi: announce withheld G17 compute doorbells whenever retiremen…
DjDeveloperr Oct 25, 2026
a5f0863
drm/asahi: build the G17 driver without warnings
DjDeveloperr Oct 25, 2026
870e51b
drm/asahi: renew G17 job deadlines while the GPU keeps retiring work
DjDeveloperr Oct 25, 2026
6fafec6
drm/asahi: kill closed G17 contexts only while no other work runs
DjDeveloperr Oct 25, 2026
4ef3920
drm/asahi: fail G17 render groups a recovery dropped out of order at …
DjDeveloperr Oct 25, 2026
045f59c
drm/asahi: announce withheld G17 compute doorbells after a recovery
DjDeveloperr Oct 25, 2026
b8b841f
drm/asahi: move the G17 cumulative-signals feature to bit 29
DjDeveloperr Oct 25, 2026
2ca0779
drm/asahi: build the G17 compute QID budget test against the variant …
DjDeveloperr Oct 26, 2026
ee16ba0
drm/asahi: check the G17 QID floor test against the open-queue comput…
DjDeveloperr Oct 26, 2026
578dd95
drm/asahi: check the G17 admission churn test against its deadline, n…
DjDeveloperr Oct 26, 2026
691c687
Merge branch 'integration/aurora' into neo/g17-neo-perf-20261025
DjDeveloperr Oct 28, 2026
18c6404
drm/asahi: m3: admit clients that ask for the parameters up to the HA…
DjDeveloperr Oct 28, 2026
1032928
drm/asahi: apply the GPU memory limits and RSS attribution to G17 only
DjDeveloperr Oct 28, 2026
6c66b41
drm/asahi: restore the DRM driver's module owner
DjDeveloperr Oct 29, 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
29 changes: 15 additions & 14 deletions drivers/dma-buf/dma-fence-array.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,17 +107,11 @@ static bool dma_fence_array_signaled(struct dma_fence *fence)
unsigned int i;

/*
* We need to read num_pending before checking the enable_signal bit
* to avoid racing with the enable_signaling() implementation, which
* might decrement the counter, and cause a partial check.
* atomic_read_acquire() pairs with atomic_dec_and_test() in
* dma_fence_array_enable_signaling()
*
* The !--num_pending check is here to account for the any_signaled case
* if we race with enable_signaling(), that means the !num_pending check
* in the is_signalling_enabled branch might be outdated (num_pending
* might have been decremented), but that's fine. The user will get the
* right value when testing again later.
* Read the counter before the enable bit so callback installation
* cannot make a partial count look complete. The acquire pairs with
* the counter decrements in dma_fence_array_enable_signaling().
* If enabling races with the lazy scan, every child must still be
* observed complete before that scan can return true.
*/
num_pending = atomic_read_acquire(&array->num_pending);
if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &array->base.flags)) {
Expand All @@ -126,8 +120,16 @@ static bool dma_fence_array_signaled(struct dma_fence *fence)
return false;
}

/*
* Arrays require every member to complete. A pending member already
* proves the array incomplete; polling its successors only repeats work
* during timeline-chain walks. Keep the completion counter and the
* enabled-signaling path unchanged.
*/
for (i = 0; i < array->num_fences; ++i) {
if (dma_fence_is_signaled(array->fences[i]) && !--num_pending)
if (!dma_fence_is_signaled(array->fences[i]))
return false;
if (!--num_pending)
goto signal;
}
return false;
Expand Down Expand Up @@ -256,8 +258,7 @@ EXPORT_SYMBOL(dma_fence_array_init);
* and fill it with the fences it wants to add to the object. Ownership of this
* array is taken and dma_fence_put() is used on each fence on release.
*
* If @signal_on_any is true the fence array signals if any fence in the array
* signals, otherwise it signals when all fences in the array signal.
* The array signals when every fence in the array signals.
*/
struct dma_fence_array *dma_fence_array_create(int num_fences,
struct dma_fence **fences,
Expand Down
75 changes: 75 additions & 0 deletions drivers/dma-buf/st-dma-fence-unwrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,26 @@
struct mock_fence {
struct dma_fence base;
spinlock_t lock;
atomic_t polls;
};

static const char *mock_name(struct dma_fence *f)
{
return "mock";
}

static bool mock_signaled(struct dma_fence *fence)
{
struct mock_fence *f = container_of(fence, struct mock_fence, base);

atomic_inc(&f->polls);
return false;
}

static const struct dma_fence_ops mock_ops = {
.get_driver_name = mock_name,
.get_timeline_name = mock_name,
.signaled = mock_signaled,
};

static struct dma_fence *__mock_fence(u64 context, u64 seqno)
Expand All @@ -36,6 +46,7 @@ static struct dma_fence *__mock_fence(u64 context, u64 seqno)
return NULL;

spin_lock_init(&f->lock);
atomic_set(&f->polls, 0);
dma_fence_init(&f->base, &mock_ops, &f->lock, context, seqno);

return &f->base;
Expand Down Expand Up @@ -584,7 +595,71 @@ static void test_unwrap_merge_complex_seqno(struct kunit *test)
dma_fence_put(f1);
}

/*
* A pending all-of array needs no polls of later members. Keep its
* independent member fences so their polling and out-of-order completion
* remain observable without enabling callbacks on the array.
*/
static void test_array_pending_prefix(struct kunit *test)
{
struct dma_fence *first = mock_fence(), *last = mock_fence();
struct dma_fence *array;
struct mock_fence *last_mock;

if (!first || !last) {
KUNIT_FAIL(test, "Could not allocate member fences");
goto out;
}
last_mock = container_of(last, struct mock_fence, base);
array = mock_array(2, dma_fence_get(first), dma_fence_get(last));
if (!array) {
KUNIT_FAIL(test, "Could not allocate fence array");
goto out;
}
KUNIT_EXPECT_FALSE(test, dma_fence_is_signaled(array));
KUNIT_EXPECT_EQ(test, atomic_read(&last_mock->polls), 0);
dma_fence_signal(last);
KUNIT_EXPECT_FALSE(test, dma_fence_is_signaled(array));
dma_fence_signal(first);
KUNIT_EXPECT_TRUE(test, dma_fence_is_signaled(array));
dma_fence_put(array);
out:
dma_fence_put(last);
dma_fence_put(first);
}

static void test_array_pending_suffix(struct kunit *test)
{
struct dma_fence *first = mock_fence(), *last = mock_fence();
struct dma_fence *array;

if (!first || !last) {
KUNIT_FAIL(test, "Could not allocate member fences");
goto out;
}
array = mock_array(2, dma_fence_get(first), dma_fence_get(last));
if (!array) {
KUNIT_FAIL(test, "Could not allocate fence array");
goto out;
}
dma_fence_signal(first);
KUNIT_EXPECT_FALSE(test, dma_fence_is_signaled(array));
/* Installing callbacks after a lazy partial poll must still account
* for the already signaled first member and wait for the last.
*/
dma_fence_enable_signaling(array);
KUNIT_EXPECT_FALSE(test, dma_fence_is_signaled(array));
dma_fence_signal(last);
KUNIT_EXPECT_GT(test, dma_fence_wait_timeout(array, false, HZ), 0L);
dma_fence_put(array);
out:
dma_fence_put(last);
dma_fence_put(first);
}

static struct kunit_case dma_fence_unwrap_cases[] = {
KUNIT_CASE(test_array_pending_prefix),
KUNIT_CASE(test_array_pending_suffix),
KUNIT_CASE(test_sanitycheck),
KUNIT_CASE(test_unwrap_array),
KUNIT_CASE(test_unwrap_chain),
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/asahi/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# 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 g17/sync_input.o g17/sync_output.o g17/sync_scope.o g17/trace.o
CFLAGS_g17/trace.o := -I$(src)/g17

asahi-$(CONFIG_DRM_ASAHI_G15) += g15/glue.o
asahi-$(CONFIG_DRM_ASAHI_UAT_ADOPTION) += g15/uat_glue.o
14 changes: 14 additions & 0 deletions drivers/gpu/drm/asahi/asahi_core.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// SPDX-License-Identifier: GPL-2.0-only OR MIT
#![recursion_limit = "2048"]

Expand Down Expand Up @@ -25,6 +25,7 @@
mod hw;
mod initdata;
mod mem;
mod memacct;
mod m3;
mod microseq;
mod mmu;
Expand All @@ -35,6 +36,7 @@
mod slotalloc;
mod stats;
mod sysfs_exports;
mod timestamp;
mod util;
#[cfg(CONFIG_DRM_ASAHI_MAPLE_TREE)]
mod vm;
Expand Down Expand Up @@ -172,5 +174,17 @@
// permissions: 0,
description: "Export AGX firmware stats to sysfs (1 = on, 0 = off)",
},
mem_limit_pct: u32 {
Comment thread
maralcbr marked this conversation as resolved.
Resolved
default: 67,
description: "G17: device-wide GPU memory limit in percent of RAM (0 or >= 100: none)",
},
client_mem_limit_pct: u32 {
default: 50,
description: "G17: per-client GPU memory limit in percent of RAM (0: the device limit)",
},
oom_attribution: u8 {
default: 1,
description: "G17: count held GPU memory in its creator's RSS for the OOM killer (1 = on)",
},
},
}
17 changes: 16 additions & 1 deletion drivers/gpu/drm/asahi/driver.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// SPDX-License-Identifier: GPL-2.0-only OR MIT

//! Top-level GPU driver implementation.
Expand Down Expand Up @@ -91,6 +91,10 @@
desc: c"Apple AGX Graphics",
};

// Open DRM files and exported DMA buffers take their callbacks' module from `MODULE`. With
// `None`, a modular build could be unloaded while they still point into it.
const _: () = assert!(<AsahiDrmDriver as drm::driver::Driver>::MODULE.is_some());

/// DRM Driver implementation for `AsahiDriver`.
#[vtable]
impl drm::driver::Driver for AsahiDrmDriver {
Expand Down Expand Up @@ -153,6 +157,10 @@
of::DeviceId::new(c"apple,agx-t8140"),
ProbeConfig::G17(&hw::t8140::CONFIG)
),
(
of::DeviceId::new(c"apple,agx-t6040"),
Comment thread
maralcbr marked this conversation as resolved.
Resolved
ProbeConfig::G17(&hw::t6040::CONFIG)
),
(
of::DeviceId::new(c"apple,agx-t8103"),
ProbeConfig::Legacy(&hw::t8103::HWCONFIG)
Expand Down Expand Up @@ -390,6 +398,8 @@
pdev: &'bound platform::Device<Core<'_>>,
cfg: &'static g17::Config,
) -> Result<AsahiPlatformDriverData<'bound>> {
// The GPU memory limits and RSS attribution apply only to G17 for now.
crate::memacct::LEDGER.configure();
// SAFETY: The GPU performs DMA through a UAT whose output width is part of the SoC config.
unsafe { pdev.dma_set_mask_and_coherent(DmaMask::try_new(cfg.uat_oas)?)? };
let resources = regs::Resources::new(pdev)?;
Expand Down Expand Up @@ -419,6 +429,11 @@
return Err(error);
}
};
if let Err(error) =
crate::sysfs_exports::register_idle(raw_dev, crate::g17::power::IDLE_HOLD_MS.as_ptr())
{
dev_warn!(pdev.as_ref(), "idle_off_delay_ms not registered: {:?}\n", error);
}
Ok(AsahiPlatformDriverData {
_device: reg.device().into(),
_reg: reg,
Expand All @@ -433,7 +448,7 @@

impl Drop for AsahiPlatformDriverData<'_> {
fn drop(&mut self) {
// SAFETY: `self.raw_dev` was set in `probe` from the platform
// `self.raw_dev` was set in `probe` from the platform
// device's `as_raw()`, valid for the lifetime of the bound driver.
if !self.raw_dev.is_null() {
crate::sysfs_exports::unregister(self.raw_dev, self.raw_stats);
Expand Down
Loading
Loading