Skip to content

Commit 7307fdf

Browse files
hoshinolinajannau
authored andcommitted
drm/asahi: workqueue: Defer freeing the last completed work item
Maybe helps with firmware crashes? Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent 03802ac commit 7307fdf

1 file changed

Lines changed: 18 additions & 1 deletion

File tree

drivers/gpu/drm/asahi/workqueue.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ struct WorkQueueInner {
255255
size: u32,
256256
wptr: u32,
257257
pending: KVec<Pin<KBox<SubmittedWorkContainer>>>,
258+
last_completed_work: Option<Pin<KBox<SubmittedWorkContainer>>>,
258259
last_token: Option<event::Token>,
259260
pending_jobs: usize,
260261
last_submitted: Option<event::EventValue>,
@@ -736,6 +737,7 @@ impl WorkQueue::ver {
736737
size,
737738
wptr: 0,
738739
pending: KVec::new(),
740+
last_completed_work: None,
739741
last_token: None,
740742
event: None,
741743
priority,
@@ -929,16 +931,22 @@ impl WorkQueue for WorkQueue::ver {
929931
let last_wptr = inner.pending[completed_commands - 1].inner.wptr();
930932
let pipe_type = inner.pipe_type;
931933

934+
let mut last_cmd = inner.last_completed_work.take();
935+
932936
for mut cmd in inner.pending.drain(..completed_commands) {
933937
mod_pr_debug!(
934938
"WorkQueue({:?}): Queueing command @ {:?} for cleanup\n",
935939
pipe_type,
936940
cmd.inner.gpu_va()
937941
);
938942
cmd.as_mut().inner_mut().complete();
939-
workqueue::system().enqueue(cmd);
943+
if let Some(last_cmd) = last_cmd.replace(cmd) {
944+
workqueue::system().enqueue(last_cmd);
945+
}
940946
}
941947

948+
inner.last_completed_work = last_cmd;
949+
942950
mod_pr_debug!(
943951
"WorkQueue({:?}): Completed {} commands, left pending {}, ls {:#x?}, lc {:#x?}\n",
944952
inner.pipe_type,
@@ -1035,3 +1043,12 @@ impl WorkQueue for WorkQueue::ver {
10351043
}
10361044
}
10371045
}
1046+
1047+
#[versions(AGX)]
1048+
impl Drop for WorkQueueInner::ver {
1049+
fn drop(&mut self) {
1050+
if let Some(last_cmd) = self.last_completed_work.take() {
1051+
workqueue::system().enqueue(last_cmd);
1052+
}
1053+
}
1054+
}

0 commit comments

Comments
 (0)