@@ -3466,40 +3466,19 @@ impl MemoryManager {
34663466 where
34673467 L : LockBefore < MmDumpable > ,
34683468 {
3469- // TODO(https://fxbug.dev/42074633): When SNAPSHOT (or equivalent) is supported on pager-backed VMOs
3470- // we can remove the hack below (which also won't be performant). For now, as a workaround,
3471- // we use SNAPSHOT_AT_LEAST_ON_WRITE on both the child and the parent.
3472-
3473- struct MemoryInfo {
3474- memory : Arc < MemoryObject > ,
3475- size : u64 ,
3476-
3477- // Indicates whether or not the memory object needs to be replaced on the parent as
3478- // well.
3479- needs_snapshot_on_parent : bool ,
3480- }
3481-
34823469 // Clones the `memory` and returns the `MemoryInfo` with the clone.
34833470 fn clone_memory (
34843471 memory : & Arc < MemoryObject > ,
34853472 rights : zx:: Rights ,
3486- ) -> Result < MemoryInfo , Errno > {
3473+ ) -> Result < Arc < MemoryObject > , Errno > {
34873474 let memory_info = memory. info ( ) ?;
34883475 let pager_backed = memory_info. flags . contains ( zx:: VmoInfoFlags :: PAGER_BACKED ) ;
34893476 Ok ( if pager_backed && !rights. contains ( zx:: Rights :: WRITE ) {
3490- MemoryInfo {
3491- memory : memory. clone ( ) ,
3492- size : memory_info. size_bytes ,
3493- needs_snapshot_on_parent : false ,
3494- }
3477+ memory. clone ( )
34953478 } else {
34963479 let mut cloned_memory = memory
34973480 . create_child (
3498- if pager_backed {
3499- zx:: VmoChildOptions :: SNAPSHOT_AT_LEAST_ON_WRITE
3500- } else {
3501- zx:: VmoChildOptions :: SNAPSHOT
3502- } | zx:: VmoChildOptions :: RESIZABLE ,
3481+ zx:: VmoChildOptions :: SNAPSHOT_MODIFIED | zx:: VmoChildOptions :: RESIZABLE ,
35033482 0 ,
35043483 memory_info. size_bytes ,
35053484 )
@@ -3509,54 +3488,28 @@ impl MemoryManager {
35093488 . replace_as_executable ( & VMEX_RESOURCE )
35103489 . map_err ( impossible_error) ?;
35113490 }
3512- MemoryInfo {
3513- memory : Arc :: new ( cloned_memory) ,
3514- size : memory_info. size_bytes ,
3515- needs_snapshot_on_parent : pager_backed,
3516- }
3517- } )
3518- }
3519-
3520- fn snapshot_memory (
3521- memory : & MemoryObject ,
3522- size : u64 ,
3523- rights : zx:: Rights ,
3524- ) -> Result < Arc < MemoryObject > , Errno > {
3525- let mut cloned_memory = memory
3526- . create_child (
3527- zx:: VmoChildOptions :: SNAPSHOT_AT_LEAST_ON_WRITE
3528- | zx:: VmoChildOptions :: RESIZABLE ,
3529- 0 ,
3530- size,
3531- )
3532- . map_err ( MemoryManager :: get_errno_for_map_err) ?;
35333491
3534- if rights. contains ( zx:: Rights :: EXECUTE ) {
3535- cloned_memory = cloned_memory
3536- . replace_as_executable ( & VMEX_RESOURCE )
3537- . map_err ( impossible_error) ?;
3538- }
3539- Ok ( Arc :: new ( cloned_memory) )
3492+ Arc :: new ( cloned_memory)
3493+ } )
35403494 }
35413495
35423496 // Hold the lock throughout the operation to uphold memory manager's invariants.
35433497 // See mm/README.md.
35443498 let state: & mut MemoryManagerState = & mut self . state . write ( ) ;
35453499 let mut target_state = target. state . write ( ) ;
3546- let mut child_memorys = HashMap :: < zx:: Koid , MemoryInfo > :: new ( ) ;
3547- let mut replaced_memorys = HashMap :: < zx:: Koid , Arc < MemoryObject > > :: new ( ) ;
3500+ let mut clone_cache = HashMap :: < zx:: Koid , Arc < MemoryObject > > :: new ( ) ;
35483501
35493502 #[ cfg( feature = "alternate_anon_allocs" ) ]
35503503 {
35513504 let backing_size = ( state. user_vmar_info . base + state. user_vmar_info . len ) as u64 ;
35523505 target_state. private_anonymous = state. private_anonymous . snapshot ( backing_size) ?;
35533506 }
35543507
3555- for ( range, mapping) in state. mappings . iter_mut ( ) {
3508+ for ( range, mapping) in state. mappings . iter ( ) {
35563509 if mapping. flags . contains ( MappingFlags :: DONTFORK ) {
35573510 continue ;
35583511 }
3559- match & mut mapping. backing {
3512+ match & mapping. backing {
35603513 MappingBacking :: Memory ( backing) => {
35613514 let memory_offset = backing. memory_offset + ( range. start - backing. base ) as u64 ;
35623515 let length = range. end - range. start ;
@@ -3571,37 +3524,12 @@ impl MemoryManager {
35713524 create_anonymous_mapping_memory ( length as u64 ) ?
35723525 } else {
35733526 let basic_info = backing. memory . basic_info ( ) ;
3574-
3575- let MemoryInfo { memory, size : memory_size, needs_snapshot_on_parent } =
3576- match child_memorys. entry ( basic_info. koid ) {
3577- Entry :: Occupied ( o) => o. into_mut ( ) ,
3578- Entry :: Vacant ( v) => {
3579- v. insert ( clone_memory ( & backing. memory , basic_info. rights ) ?)
3580- }
3581- } ;
3582-
3583- if * needs_snapshot_on_parent {
3584- let replaced_memory = match replaced_memorys. entry ( basic_info. koid ) {
3585- Entry :: Occupied ( o) => o. into_mut ( ) ,
3586- Entry :: Vacant ( v) => v. insert ( snapshot_memory (
3587- & backing. memory ,
3588- * memory_size,
3589- basic_info. rights ,
3590- ) ?) ,
3591- } ;
3592- map_in_vmar (
3593- & state. user_vmar ,
3594- & state. user_vmar_info ,
3595- SelectedAddress :: FixedOverwrite ( range. start ) ,
3596- replaced_memory,
3597- memory_offset,
3598- length,
3599- mapping. flags ,
3600- false ,
3601- ) ?;
3602-
3603- backing. memory = replaced_memory. clone ( ) ;
3604- }
3527+ let memory = match clone_cache. entry ( basic_info. koid ) {
3528+ Entry :: Occupied ( o) => o. into_mut ( ) ,
3529+ Entry :: Vacant ( v) => {
3530+ v. insert ( clone_memory ( & backing. memory , basic_info. rights ) ?)
3531+ }
3532+ } ;
36053533 memory. clone ( )
36063534 } ;
36073535
0 commit comments