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 ++++++++++++++++++++++++++-- src/mem/physical.hh | 6 +++++- src/sim/System.py | 7 +++++++ src/sim/system.cc | 2 +- 4 files changed, 39 insertions(+), 4 deletions(-) (limited to 'src') 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); 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> 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& _memories); + const std::vector& _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), -- cgit v1.2.3