diff options
author | Andreas Hansson <andreas.hansson@arm.com> | 2015-02-16 03:33:47 -0500 |
---|---|---|
committer | Andreas Hansson <andreas.hansson@arm.com> | 2015-02-16 03:33:47 -0500 |
commit | e17328a227a47089e6f3c8fd82cc988f03807549 (patch) | |
tree | c78336b4caff2c1ab31180efdd4c8298c890aee6 /src/mem | |
parent | 57758ca685fe1a736cfdc214785b04441e83e53a (diff) | |
download | gem5-e17328a227a47089e6f3c8fd82cc988f03807549.tar.xz |
mem: mmap the backing store with MAP_NORESERVE
This patch ensures we can run simulations with very large simulated
memories (at least 64 TB based on some quick runs on a Linux
workstation). In essence this allows us to efficiently deal with
sparse address maps without having to implement a redirection layer in
the backing store.
This opens up for run-time errors if we eventually exhausts the hosts
memory and swap space, but this should hopefully never happen.
Diffstat (limited to 'src/mem')
-rw-r--r-- | src/mem/physical.cc | 28 | ||||
-rw-r--r-- | src/mem/physical.hh | 6 |
2 files changed, 31 insertions, 3 deletions
diff --git a/src/mem/physical.cc b/src/mem/physical.cc index b5627cfa2..e6d682624 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -56,12 +56,29 @@ #include "mem/abstract_mem.hh" #include "mem/physical.hh" +/** + * On Linux, MAP_NORESERVE allow us to simulate a very large memory + * without committing to actually providing the swap space on the + * host. On OSX the MAP_NORESERVE flag does not exist, so simply make + * it 0. + */ +#if defined(__APPLE__) +#ifndef MAP_NORESERVE +#define MAP_NORESERVE 0 +#endif +#endif + using namespace std; PhysicalMemory::PhysicalMemory(const string& _name, - const vector<AbstractMemory*>& _memories) : - _name(_name), rangeCache(addrMap.end()), size(0) + const vector<AbstractMemory*>& _memories, + bool mmap_using_noreserve) : + _name(_name), rangeCache(addrMap.end()), size(0), + mmapUsingNoReserve(mmap_using_noreserve) { + if (mmap_using_noreserve) + warn("Not reserving swap space. May cause SIGSEGV on actual usage\n"); + // add the memories from the system to the address map as // appropriate for (const auto& m : _memories) { @@ -148,6 +165,13 @@ PhysicalMemory::createBackingStore(AddrRange range, DPRINTF(AddrRanges, "Creating backing store for range %s with size %d\n", range.to_string(), range.size()); int map_flags = MAP_ANON | MAP_PRIVATE; + + // to be able to simulate very large memories, the user can opt to + // pass noreserve to mmap + if (mmapUsingNoReserve) { + map_flags |= MAP_NORESERVE; + } + uint8_t* pmem = (uint8_t*) mmap(NULL, range.size(), PROT_READ | PROT_WRITE, map_flags, -1, 0); diff --git a/src/mem/physical.hh b/src/mem/physical.hh index b8d26fd4b..0f53b1d9d 100644 --- a/src/mem/physical.hh +++ b/src/mem/physical.hh @@ -85,6 +85,9 @@ class PhysicalMemory : public Serializable // The total memory size uint64_t size; + // Let the user choose if we reserve swap space when calling mmap + const bool mmapUsingNoReserve; + // The physical memory used to provide the memory in the simulated // system std::vector<std::pair<AddrRange, uint8_t*>> backingStore; @@ -112,7 +115,8 @@ class PhysicalMemory : public Serializable * Create a physical memory object, wrapping a number of memories. */ PhysicalMemory(const std::string& _name, - const std::vector<AbstractMemory*>& _memories); + const std::vector<AbstractMemory*>& _memories, + bool mmap_using_noreserve); /** * Unmap all the backing store we have used. |