@@ -18,8 +18,8 @@ use core::sync::atomic::{fence, AtomicU32, AtomicU64, AtomicU8, Ordering};
1818use core:: time:: Duration ;
1919
2020use 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`].
581581pub ( 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