Skip to content

Commit 066e6e2

Browse files
hoshinolinajannau
authored andcommitted
drm/asahi: mmu: Fix lockdep issues with GpuVm
Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent 258e3ea commit 066e6e2

1 file changed

Lines changed: 14 additions & 3 deletions

File tree

drivers/gpu/drm/asahi/mmu.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use core::sync::atomic::{fence, AtomicU32, AtomicU64, AtomicU8, Ordering};
1818
use core::time::Duration;
1919

2020
use kernel::{
21-
bindings, c_str, delay, device,
22-
drm::{gpuvm, mm},
21+
bindings, c_str, delay, device, drm,
22+
drm::{gem::BaseObject, gpuvm, mm},
2323
error::{to_result, Result},
2424
io_pgtable,
2525
io_pgtable::{prot, AppleUAT, IoPageTable},
@@ -579,11 +579,16 @@ impl Clone for VmBind {
579579

580580
/// Inner data required for an object mapping into a [`Vm`].
581581
pub(crate) struct KernelMappingInner {
582+
// Drop order matters:
583+
// - Drop the GpuVmBo first, which resv locks its BO and drops a GpuVm reference
584+
// - Drop the GEM BO next, since BO free can take the resv lock itself
585+
// - Drop the owner GpuVm last, since that again can take resv locks when the refcount drops to 0
586+
bo: Option<ARef<gpuvm::GpuVmBo<VmInner>>>,
587+
_gem: Option<drm::gem::ObjectRef<gem::Object>>,
582588
owner: ARef<gpuvm::GpuVm<VmInner>>,
583589
uat_inner: Arc<UatInner>,
584590
prot: u32,
585591
mapped_size: usize,
586-
bo: Option<ARef<gpuvm::GpuVmBo<VmInner>>>,
587592
}
588593

589594
/// An object mapping into a [`Vm`], which reserves the address range from use by other mappings.
@@ -1097,6 +1102,7 @@ impl Vm {
10971102
uat_inner,
10981103
prot,
10991104
bo: Some(vm_bo),
1105+
_gem: Some(gem.reference()),
11001106
mapped_size: size,
11011107
},
11021108
(size + if guard { UAT_PGSZ } else { 0 }) as u64, // Add guard page
@@ -1139,6 +1145,7 @@ impl Vm {
11391145
uat_inner,
11401146
prot,
11411147
bo: Some(vm_bo),
1148+
_gem: Some(gem.reference()),
11421149
mapped_size: size,
11431150
},
11441151
addr,
@@ -1239,6 +1246,7 @@ impl Vm {
12391246
uat_inner,
12401247
prot,
12411248
bo: None,
1249+
_gem: None,
12421250
mapped_size: size,
12431251
},
12441252
iova,
@@ -1278,6 +1286,9 @@ impl Vm {
12781286
mod_dev_dbg!(inner.dev, "MMU: bo_unmap\n");
12791287
inner.bo_unmap(&mut ctx, &bo)?;
12801288
mod_dev_dbg!(inner.dev, "MMU: bo_unmap done\n");
1289+
// We need to drop the exec_lock first, then the GpuVmBo since that will take the lock itself.
1290+
core::mem::drop(inner);
1291+
core::mem::drop(bo);
12811292
}
12821293

12831294
Ok(())

0 commit comments

Comments
 (0)