@@ -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.
@@ -1090,6 +1095,7 @@ impl Vm {
10901095 uat_inner,
10911096 prot,
10921097 bo : Some ( vm_bo) ,
1098+ _gem : Some ( gem. reference ( ) ) ,
10931099 mapped_size : size,
10941100 } ,
10951101 ( size + if guard { UAT_PGSZ } else { 0 } ) as u64 , // Add guard page
@@ -1132,6 +1138,7 @@ impl Vm {
11321138 uat_inner,
11331139 prot,
11341140 bo : Some ( vm_bo) ,
1141+ _gem : Some ( gem. reference ( ) ) ,
11351142 mapped_size : size,
11361143 } ,
11371144 addr,
@@ -1232,6 +1239,7 @@ impl Vm {
12321239 uat_inner,
12331240 prot,
12341241 bo : None ,
1242+ _gem : None ,
12351243 mapped_size : size,
12361244 } ,
12371245 iova,
@@ -1271,6 +1279,9 @@ impl Vm {
12711279 mod_dev_dbg ! ( inner. dev, "MMU: bo_unmap\n " ) ;
12721280 inner. bo_unmap ( & mut ctx, & bo) ?;
12731281 mod_dev_dbg ! ( inner. dev, "MMU: bo_unmap done\n " ) ;
1282+ // We need to drop the exec_lock first, then the GpuVmBo since that will take the lock itself.
1283+ core:: mem:: drop ( inner) ;
1284+ core:: mem:: drop ( bo) ;
12741285 }
12751286
12761287 Ok ( ( ) )
0 commit comments