[gem5-dev] Change in gem5/gem5[develop]: sim-se: Update mmap, munmap, mremap to use MemState

2020-03-25 Thread Matthew Poremba (Gerrit)
Matthew Poremba has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/26863 )


Change subject: sim-se: Update mmap, munmap, mremap to use MemState
..

sim-se: Update mmap, munmap, mremap to use MemState

This updates the syscalls for mmap, munmap, and mremap. The mmap
changes now create a virtual memory area through the MemState class
to allow for lazy allocation of mmapped regions. This provides
substantial performance boost for sparse usage of mmaps. The munmap
syscall is added to reclaim the virtual memory area reserved for the
mmapped region. The mremap syscall moves or resizes an mmapped region
and updates the corresponding virtual memory area region to keep the
page tables in sync.

Change-Id: Ide158e69cdff19bc81157e3e9826bcabc2a51140
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/26863
Tested-by: Gem5 Cloud Project GCB service account  
<345032938...@cloudbuild.gserviceaccount.com>

Tested-by: kokoro 
Reviewed-by: Jason Lowe-Power 
Maintainer: Jason Lowe-Power 
---
M src/sim/syscall_emul.cc
M src/sim/syscall_emul.hh
2 files changed, 111 insertions(+), 116 deletions(-)

Approvals:
  Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass
  Gem5 Cloud Project GCB service account: Regressions pass



diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index 08432e1..bffedfd 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -326,11 +326,22 @@


 SyscallReturn
-munmapFunc(SyscallDesc *desc, ThreadContext *tc)
+munmapFunc(SyscallDesc *desc, ThreadContext *tc, Addr start, size_t length)
 {
-// With mmap more fully implemented, it might be worthwhile to bite
-// the bullet and implement munmap. Should allow us to reuse simulated
-// memory.
+// Even if the system is currently not capable of recycling physical
+// pages, there is no reason we can't unmap them so that we trigger
+// appropriate seg faults when the application mistakenly tries to
+// access them again.
+auto p = tc->getProcessPtr();
+
+if (start & (tc->getSystemPtr()->getPageBytes() - 1) || !length) {
+return -EINVAL;
+}
+
+length = roundUp(length, tc->getSystemPtr()->getPageBytes());
+
+p->memState->unmapRegion(start, length);
+
 return 0;
 }

diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 8fc8994..1270855 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -165,7 +165,8 @@
   uint32_t offset_low, Addr result_ptr, int  
whence);


 /// Target munmap() handler.
-SyscallReturn munmapFunc(SyscallDesc *desc, ThreadContext *tc);
+SyscallReturn munmapFunc(SyscallDesc *desc, ThreadContext *tc, Addr start,
+ size_t length);

 /// Target shutdown() handler.
 SyscallReturn shutdownFunc(SyscallDesc *desc, ThreadContext *tc,
@@ -1112,32 +1113,32 @@
 Addr start, uint64_t old_length, uint64_t new_length, uint64_t  
flags,

 GuestABI::VarArgs varargs)
 {
-auto process = tc->getProcessPtr();
+auto p = tc->getProcessPtr();
+Addr page_bytes = tc->getSystemPtr()->getPageBytes();
 uint64_t provided_address = 0;
 bool use_provided_address = flags & OS::TGT_MREMAP_FIXED;

 if (use_provided_address)
 provided_address = varargs.get();

-if ((start % TheISA::PageBytes != 0) ||
-(provided_address % TheISA::PageBytes != 0)) {
+if ((start % page_bytes != 0) ||
+(provided_address % page_bytes != 0)) {
 warn("mremap failing: arguments not page aligned");
 return -EINVAL;
 }

-new_length = roundUp(new_length, TheISA::PageBytes);
+new_length = roundUp(new_length, page_bytes);

 if (new_length > old_length) {
-std::shared_ptr mem_state = process->memState;
-Addr mmap_end = mem_state->getMmapEnd();
+Addr mmap_end = p->memState->getMmapEnd();

 if ((start + old_length) == mmap_end &&
 (!use_provided_address || provided_address == start)) {
 // This case cannot occur when growing downward, as
 // start is greater than or equal to mmap_end.
 uint64_t diff = new_length - old_length;
-process->allocateMem(mmap_end, diff);
-mem_state->setMmapEnd(mmap_end + diff);
+p->memState->mapRegion(mmap_end, diff, "remapped");
+p->memState->setMmapEnd(mmap_end + diff);
 return start;
 } else {
 if (!use_provided_address && !(flags &  
OS::TGT_MREMAP_MAYMOVE)) {

@@ -1146,38 +1147,45 @@
 } else {
 uint64_t new_start = provided_address;
 if (!use_provided_address) {
-new_start = process->mmapGrowsDown() ?
+new_start = p->mmapGrowsDown() ?
 mmap_end - new_length : mmap_end;
-  

[gem5-dev] Change in gem5/gem5[develop]: sim-se: Update mmap, munmap, mremap to use MemState

2020-03-17 Thread Matthew Poremba (Gerrit)
Matthew Poremba has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/26863 )



Change subject: sim-se: Update mmap, munmap, mremap to use MemState
..

sim-se: Update mmap, munmap, mremap to use MemState

This updates the syscalls for mmap, munmap, and mremap. The mmap
changes now create a virtual memory area through the MemState class
to allow for lazy allocation of mmapped regions. This provides
substantial performance boost for sparse usage of mmaps. The munmap
syscall is added to reclaim the virtual memory area reserved for the
mmapped region. The mremap syscall moves or resizes an mmapped region
and updates the corresponding virtual memory area region to keep the
page tables in sync.

Change-Id: Ide158e69cdff19bc81157e3e9826bcabc2a51140
---
M src/sim/syscall_emul.cc
M src/sim/syscall_emul.hh
2 files changed, 112 insertions(+), 116 deletions(-)



diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index 66cc629..7c36c54 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -331,11 +331,23 @@


 SyscallReturn
-munmapFunc(SyscallDesc *desc, int num, ThreadContext *tc)
+munmapFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr start,
+   size_t length)
 {
-// With mmap more fully implemented, it might be worthwhile to bite
-// the bullet and implement munmap. Should allow us to reuse simulated
-// memory.
+// Even if the system is currently not capable of recycling physical
+// pages, there is no reason we can't unmap them so that we trigger
+// appropriate seg faults when the application mistakenly tries to
+// access them again.
+auto p = tc->getProcessPtr();
+
+if (start & (tc->getSystemPtr()->getPageBytes() - 1) || !length) {
+return -EINVAL;
+}
+
+length = roundUp(length, tc->getSystemPtr()->getPageBytes());
+
+p->memState->unmapRegion(start, length);
+
 return 0;
 }

diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index f999e45..cd57e3e 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -169,7 +169,8 @@
   uint32_t offset_low, Addr result_ptr, int  
whence);


 /// Target munmap() handler.
-SyscallReturn munmapFunc(SyscallDesc *desc, int num, ThreadContext *tc);
+SyscallReturn munmapFunc(SyscallDesc *desc, int num, ThreadContext *tc,
+ Addr start, size_t length);

 /// Target shutdown() handler.
 SyscallReturn shutdownFunc(SyscallDesc *desc, int num, ThreadContext *tc,
@@ -1123,32 +1124,32 @@
 Addr start, uint64_t old_length, uint64_t new_length, uint64_t  
flags,

 GuestABI::VarArgs varargs)
 {
-auto process = tc->getProcessPtr();
+auto p = tc->getProcessPtr();
+Addr page_bytes = tc->getSystemPtr()->getPageBytes();
 uint64_t provided_address = 0;
 bool use_provided_address = flags & OS::TGT_MREMAP_FIXED;

 if (use_provided_address)
 provided_address = varargs.get();

-if ((start % TheISA::PageBytes != 0) ||
-(provided_address % TheISA::PageBytes != 0)) {
+if ((start % page_bytes != 0) ||
+(provided_address % page_bytes != 0)) {
 warn("mremap failing: arguments not page aligned");
 return -EINVAL;
 }

-new_length = roundUp(new_length, TheISA::PageBytes);
+new_length = roundUp(new_length, page_bytes);

 if (new_length > old_length) {
-std::shared_ptr mem_state = process->memState;
-Addr mmap_end = mem_state->getMmapEnd();
+Addr mmap_end = p->memState->getMmapEnd();

 if ((start + old_length) == mmap_end &&
 (!use_provided_address || provided_address == start)) {
 // This case cannot occur when growing downward, as
 // start is greater than or equal to mmap_end.
 uint64_t diff = new_length - old_length;
-process->allocateMem(mmap_end, diff);
-mem_state->setMmapEnd(mmap_end + diff);
+p->memState->mapRegion(mmap_end, diff, "remapped");
+p->memState->setMmapEnd(mmap_end + diff);
 return start;
 } else {
 if (!use_provided_address && !(flags &  
OS::TGT_MREMAP_MAYMOVE)) {

@@ -1157,38 +1158,45 @@
 } else {
 uint64_t new_start = provided_address;
 if (!use_provided_address) {
-new_start = process->mmapGrowsDown() ?
+new_start = p->mmapGrowsDown() ?
 mmap_end - new_length : mmap_end;
-mmap_end = process->mmapGrowsDown() ?
+mmap_end = p->mmapGrowsDown() ?
new_start : mmap_end + new_length;
-mem_state->setMmapEnd(mmap_end);
+p->memState->setMmapEnd(mmap_end);
 }

-process->pTable->remap(start, old_length, new