mem: Fix phy mem with shm and multiple abstr mem

Previously, all abstract memory backed by the same physical memory will
use the exact same chunk of shared memory if sharedBackstore is set. It
means that all abstract memories, despite setting to a different range,
will still be map to the same chunk of memory.

As a result, setting the sharedBackstore not only allows our host system
to share gem5 memory, it also enforces multiple gem5 memories to share
the same content. Which will significantly affect the simulation result.

Furthermore, the actual size of the shared memory will be determined by
the last backingStore created. If the last one is unfortunately smaller
than any previous backingStore, this may invalid previous mapped region
and cause a SIGBUS upon access (on linux).

In this CL, we put all backingStores of those abstract memories side by
side instead of stacking them all together. So the behavior of abstract
memories will be kept consistent whether the sharedBackstore is set or
not, yet presist the ability to access those memories from host.

Change-Id: Ic4ec25c99fe72744afaa2dfbb48cd0d65230e9a8
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/57369
Reviewed-by: Yu-hsin Wang <yuhsingw@google.com>
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Jui-min Lee
2022-03-07 17:49:39 +08:00
parent 288e5c47fa
commit 23e6607507
2 changed files with 11 additions and 5 deletions

View File

@@ -79,7 +79,7 @@ PhysicalMemory::PhysicalMemory(const std::string& _name,
bool mmap_using_noreserve,
const std::string& shared_backstore) :
_name(_name), size(0), mmapUsingNoReserve(mmap_using_noreserve),
sharedBackstore(shared_backstore)
sharedBackstore(shared_backstore), sharedBackstoreSize(0)
{
if (mmap_using_noreserve)
warn("Not reserving swap space. May cause SIGSEGV on actual usage\n");
@@ -201,17 +201,22 @@ PhysicalMemory::createBackingStore(
int shm_fd;
int map_flags;
off_t map_offset;
if (sharedBackstore.empty()) {
shm_fd = -1;
map_flags = MAP_ANON | MAP_PRIVATE;
map_offset = 0;
} else {
DPRINTF(AddrRanges, "Sharing backing store as %s\n",
sharedBackstore.c_str());
// Newly create backstore will be located after previous one.
map_offset = sharedBackstoreSize;
sharedBackstoreSize += range.size();
DPRINTF(AddrRanges, "Sharing backing store as %s at offset %llu\n",
sharedBackstore.c_str(), (uint64_t)map_offset);
shm_fd = shm_open(sharedBackstore.c_str(), O_CREAT | O_RDWR, 0666);
if (shm_fd == -1)
panic("Shared memory failed");
if (ftruncate(shm_fd, range.size()))
if (ftruncate(shm_fd, sharedBackstoreSize))
panic("Setting size of shared memory failed");
map_flags = MAP_SHARED;
}
@@ -224,7 +229,7 @@ PhysicalMemory::createBackingStore(
uint8_t* pmem = (uint8_t*) mmap(NULL, range.size(),
PROT_READ | PROT_WRITE,
map_flags, shm_fd, 0);
map_flags, shm_fd, map_offset);
if (pmem == (uint8_t*) MAP_FAILED) {
perror("mmap");

View File

@@ -140,6 +140,7 @@ class PhysicalMemory : public Serializable
const bool mmapUsingNoReserve;
const std::string sharedBackstore;
uint64_t sharedBackstoreSize;
// The physical memory used to provide the memory in the simulated
// system