Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 20 additions & 4 deletions drivers/gpu/drm/asahi/g17/queue/compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,8 +594,9 @@ pub(crate) struct Queue {
source_readers: Arc<core::sync::atomic::AtomicU32>,
source_hint: crate::g17::sync_input::ReaderHint,
/// The doorbell withheld from publications that had [`WITHHOLD_DEPTH`] - 1 or more
/// unretired commands of this queue ahead of them, the publication of the first, and the
/// compute work slots written at its priority once its slot was.
/// unretired commands of this queue ahead of them, the publication of the first of them
/// that no doorbell has announced, and the compute work slots written at its priority once
/// the last one's slot was.
withheld_doorbell: Option<(u64, u64, u64)>,
}

Expand Down Expand Up @@ -628,15 +629,19 @@ impl Queue {
}

/// The queue has left ordinary retirement: a timeout, kill, quarantine, replay, recovery
/// witness or exit is in progress.
/// witness or exit is in progress, or retirement stopped at a command the firmware
/// finished without a completion record. A front whose record has arrived and that only
/// waits for its stamp is ordinary retirement: [`Self::due_doorbell`] counts it as
/// finished, and ringing at once there rang most withheld doorbells early.
fn settling(&self) -> bool {
self.quarantined
|| self.released
|| self.exit.is_some()
|| self.replays.len != 0
|| self.replay_retirement
|| self.awaiting_witness
|| self.retire_pending
|| (self.retire_pending
&& self.active.front().is_none_or(|active| active.observed.is_none()))
|| self.retired_by_teardown
|| self.spared_quarantine
|| self.failure_status_pending
Expand Down Expand Up @@ -1952,6 +1957,8 @@ pub(crate) trait Host {
-> Result;
fn notify_compute(&mut self, priority: u8, message: u64) -> Result;
fn compute_written(&self, priority: u8) -> u64;
/// Compute work slots at `priority` that a doorbell has announced.
fn compute_announced(&self, priority: u8) -> u64;
fn note_submission(&mut self) -> Result;
}

Expand Down Expand Up @@ -2303,6 +2310,15 @@ impl Queue {
&& self.withheld_doorbell.is_none_or(|(withheld, _, _)| withheld == doorbell)
{
let written = host.compute_written(policy.priority());
// Once another doorbell announced every slot the withheld one covered, it
// starts over from this publication: it then waits for this command's own
// predecessors rather than for those of slots already announced.
if self
.withheld_doorbell
.is_some_and(|(_, _, last)| host.compute_announced(policy.priority()) >= last)
{
self.withheld_doorbell = None;
}
let entry = self.withheld_doorbell.get_or_insert((doorbell, published, written));
entry.2 = written;
} else {
Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/asahi/g17/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1396,6 +1396,9 @@ impl compute::Host for ComputeHost<'_> {
fn compute_written(&self, priority: u8) -> u64 {
self.port.compute_written(priority)
}
fn compute_announced(&self, priority: u8) -> u64 {
self.port.compute_announced(priority)
}
fn note_submission(&mut self) -> Result {
self.effort.submit();
super::Firmware::apply_shared_effort(self.init, self.effort, self.port, super::power::FULL_EFFORT)
Expand Down Expand Up @@ -1443,6 +1446,9 @@ impl compute::Host for DirectHost<'_> {
fn compute_written(&self, priority: u8) -> u64 {
self.port.compute_written(priority)
}
fn compute_announced(&self, priority: u8) -> u64 {
self.port.compute_announced(priority)
}
fn note_submission(&mut self) -> Result {
Ok(())
}
Expand Down