Skip to content

Commit 312ccf1

Browse files
committed
drm/asahi: mmu: Fix deadlock on remap ops
Signed-off-by: Asahi Lina <[email protected]>
1 parent 0b31a16 commit 312ccf1

1 file changed

Lines changed: 26 additions & 1 deletion

File tree

drivers/gpu/drm/asahi/mmu.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ struct StepContext {
228228
prev_va: Option<Pin<KBox<gpuvm::GpuVa<VmInner>>>>,
229229
next_va: Option<Pin<KBox<gpuvm::GpuVa<VmInner>>>>,
230230
vm_bo: Option<ARef<gpuvm::GpuVmBo<VmInner>>>,
231+
prev_vm_bo_1: Option<ARef<gpuvm::GpuVmBo<VmInner>>>,
232+
prev_vm_bo_2: Option<ARef<gpuvm::GpuVmBo<VmInner>>>,
231233
prot: u32,
232234
}
233235

@@ -372,6 +374,18 @@ impl gpuvm::DriverGpuVm for VmInner {
372374

373375
self.unmap_pages(unmap_start, UAT_PGSZ, (unmap_range >> UAT_PGBIT) as usize)?;
374376

377+
if let Some(asid) = self.slot() {
378+
mem::tlbi_range(asid as u8, unmap_start as usize, unmap_range as usize);
379+
mod_dev_dbg!(
380+
self.dev,
381+
"MMU: flush range: asid={:#x} start={:#x} len={:#x}\n",
382+
asid,
383+
unmap_start,
384+
unmap_range,
385+
);
386+
mem::sync();
387+
}
388+
375389
if op.unmap().unmap_and_unlink_va().is_none() {
376390
dev_err!(self.dev.as_ref(), "step_unmap: could not unlink gpuva");
377391
}
@@ -390,6 +404,17 @@ impl gpuvm::DriverGpuVm for VmInner {
390404
}
391405
}
392406

407+
if ctx.prev_vm_bo_1.is_none() {
408+
assert!(ctx.prev_vm_bo_1.replace(vm_bo).is_none());
409+
} else if ctx.prev_vm_bo_2.is_none() {
410+
assert!(ctx.prev_vm_bo_2.replace(vm_bo).is_none());
411+
} else {
412+
dev_crit!(
413+
self.dev.as_ref(),
414+
"step_remap: too many remap ops, deadlock expected"
415+
);
416+
}
417+
393418
Ok(())
394419
}
395420
}
@@ -1194,8 +1219,8 @@ impl Vm {
11941219
new_va: Some(gpuvm::GpuVa::<VmInner>::new(init::default())?),
11951220
prev_va: Some(gpuvm::GpuVa::<VmInner>::new(init::default())?),
11961221
next_va: Some(gpuvm::GpuVa::<VmInner>::new(init::default())?),
1197-
vm_bo: None,
11981222
prot,
1223+
..Default::default()
11991224
};
12001225

12011226
let sgt = gem.sg_table()?;

0 commit comments

Comments
 (0)