summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2015-02-16 03:33:47 -0500
committerAndreas Hansson <andreas.hansson@arm.com>2015-02-16 03:33:47 -0500
commite17328a227a47089e6f3c8fd82cc988f03807549 (patch)
treec78336b4caff2c1ab31180efdd4c8298c890aee6 /src
parent57758ca685fe1a736cfdc214785b04441e83e53a (diff)
downloadgem5-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')
-rw-r--r--src/mem/physical.cc28
-rw-r--r--src/mem/physical.hh6
-rw-r--r--src/sim/System.py7
-rw-r--r--src/sim/system.cc2
4 files changed, 39 insertions, 4 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.
diff --git a/src/sim/System.py b/src/sim/System.py
index 630cd2a84..e24a1e6b2 100644
--- a/src/sim/System.py
+++ b/src/sim/System.py
@@ -59,6 +59,13 @@ class System(MemObject):
"All memories in the system")
mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in")
+ # When reserving memory on the host, we have the option of
+ # reserving swap space or not (by passing MAP_NORESERVE to
+ # mmap). By enabling this flag, we accomodate cases where a large
+ # (but sparse) memory is simulated.
+ mmap_using_noreserve = Param.Bool(False, "mmap the backing store " \
+ "without reserving swap")
+
# The memory ranges are to be populated when creating the system
# such that these can be passed from the I/O subsystem through an
# I/O bridge or cache
diff --git a/src/sim/system.cc b/src/sim/system.cc
index c311d65b9..9bd487b03 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -88,7 +88,7 @@ System::System(Params *p)
loadAddrMask(p->load_addr_mask),
loadAddrOffset(p->load_offset),
nextPID(0),
- physmem(name() + ".physmem", p->memories),
+ physmem(name() + ".physmem", p->memories, p->mmap_using_noreserve),
memoryMode(p->mem_mode),
_cacheLineSize(p->cache_line_size),
workItemsBegin(0),