Skip to content

Commit 02b9f08

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 ceb7c73 commit 02b9f08

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
@@ -252,6 +252,7 @@ struct WorkQueueInner {
252252
size: u32,
253253
wptr: u32,
254254
pending: KVec<Pin<KBox<SubmittedWorkContainer>>>,
255+
last_completed_work: Option<Pin<KBox<SubmittedWorkContainer>>>,
255256
last_token: Option<event::Token>,
256257
pending_jobs: usize,
257258
last_submitted: Option<event::EventValue>,
@@ -733,6 +734,7 @@ impl WorkQueue::ver {
733734
size,
734735
wptr: 0,
735736
pending: KVec::new(),
737+
last_completed_work: None,
736738
last_token: None,
737739
event: None,
738740
priority,
@@ -926,16 +928,22 @@ impl WorkQueue for WorkQueue::ver {
926928
let last_wptr = inner.pending[completed_commands - 1].inner.wptr();
927929
let pipe_type = inner.pipe_type;
928930

931+
let mut last_cmd = inner.last_completed_work.take();
932+
929933
for mut cmd in inner.pending.drain(..completed_commands) {
930934
mod_pr_debug!(
931935
"WorkQueue({:?}): Queueing command @ {:?} for cleanup\n",
932936
pipe_type,
933937
cmd.inner.gpu_va()
934938
);
935939
cmd.as_mut().inner_mut().complete();
936-
workqueue::system().enqueue(cmd);
940+
if let Some(last_cmd) = last_cmd.replace(cmd) {
941+
workqueue::system().enqueue(last_cmd);
942+
}
937943
}
938944

945+
inner.last_completed_work = last_cmd;
946+
939947
mod_pr_debug!(
940948
"WorkQueue({:?}): Completed {} commands, left pending {}, ls {:#x?}, lc {:#x?}\n",
941949
inner.pipe_type,
@@ -1032,3 +1040,12 @@ impl WorkQueue for WorkQueue::ver {
10321040
}
10331041
}
10341042
}
1043+
1044+
#[versions(AGX)]
1045+
impl Drop for WorkQueueInner::ver {
1046+
fn drop(&mut self) {
1047+
if let Some(last_cmd) = self.last_completed_work.take() {
1048+
workqueue::system().enqueue(last_cmd);
1049+
}
1050+
}
1051+
}

0 commit comments

Comments
 (0)