File tree Expand file tree Collapse file tree 1 file changed +13
-0
lines changed Expand file tree Collapse file tree 1 file changed +13
-0
lines changed Original file line number Diff line number Diff line change @@ -119,6 +119,19 @@ impl<VM: VMBinding> PageResource<VM> for FreeListPageResource<VM> {
119
119
// The meta-data portion of reserved Pages was committed above.
120
120
self . commit_pages ( reserved_pages, required_pages, tls) ;
121
121
if self . protect_memory_on_release && !new_chunk {
122
+ use crate :: util:: heap:: layout:: Mmapper ;
123
+ use crate :: MMAPPER ;
124
+ // This check is necessary to prevent us from mprotecting an address that is not yet mapped by mmapper.
125
+ // See https://github.com/mmtk/mmtk-core/issues/400.
126
+ // It is possible that one thread gets a new chunk, and returns from this function. However, the Space.acquire()
127
+ // has not yet call ensure_mapped() for it. So the chunk is not yet mmapped. At this point, if another thread calls
128
+ // this function, and get a few more pages from the same chunk, it is no longer seen as 'new_chunk', and we
129
+ // will try to munprotect on it. But the chunk may not yet be mapped.
130
+ //
131
+ // If we want to improve and get rid of this loop, we need to move this munprotect to anywhere after the ensure_mapped() call
132
+ // in Space.acquire(). We can either move it the option of 'protect_on_release' to space, or have a call to page resource
133
+ // after ensure_mapped(). However, I think this is sufficient given that this option is only used for PageProtect for debugging use.
134
+ while !MMAPPER . is_mapped_address ( rtn) { }
122
135
self . munprotect ( rtn, self . free_list . size ( page_offset as _ ) as _ )
123
136
} ;
124
137
Result :: Ok ( PRAllocResult {
You can’t perform that action at this time.
0 commit comments