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.
This commit is contained in:
parent
57758ca685
commit
e17328a227
4 changed files with 39 additions and 4 deletions
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in a new issue