diff -r 1d8b01d6889f -r 40aaf1161841 src/mem/physical.hh --- a/src/mem/physical.hh Mon Feb 09 09:09:20 2015 +0000 +++ b/src/mem/physical.hh Mon Feb 09 14:32:49 2015 +0000 @@ -85,6 +85,9 @@ // 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 @@ * 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 -r 1d8b01d6889f -r 40aaf1161841 src/mem/physical.cc --- a/src/mem/physical.cc Mon Feb 09 09:09:20 2015 +0000 +++ b/src/mem/physical.cc Mon Feb 09 14:32:49 2015 +0000 @@ -56,12 +56,27 @@ #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__) +#define MAP_NORESERVE 0 +#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 +163,13 @@ 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 -r 1d8b01d6889f -r 40aaf1161841 src/sim/System.py --- a/src/sim/System.py Mon Feb 09 09:09:20 2015 +0000 +++ b/src/sim/System.py Mon Feb 09 14:32:49 2015 +0000 @@ -59,6 +59,13 @@ "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 -r 1d8b01d6889f -r 40aaf1161841 src/sim/system.cc --- a/src/sim/system.cc Mon Feb 09 09:09:20 2015 +0000 +++ b/src/sim/system.cc Mon Feb 09 14:32:49 2015 +0000 @@ -88,7 +88,7 @@ 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),