From e17328a227a47089e6f3c8fd82cc988f03807549 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Mon, 16 Feb 2015 03:33:47 -0500 Subject: 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. --- src/mem/physical.cc | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'src/mem/physical.cc') 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& _memories) : - _name(_name), rangeCache(addrMap.end()), size(0) + const vector& _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); -- cgit v1.2.3