summaryrefslogtreecommitdiff
path: root/src/mem/physical.cc
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/mem/physical.cc
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/mem/physical.cc')
-rw-r--r--src/mem/physical.cc28
1 files changed, 26 insertions, 2 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);