summaryrefslogtreecommitdiff
path: root/src/mem
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
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')
-rw-r--r--src/mem/physical.cc28
-rw-r--r--src/mem/physical.hh6
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.