55#include "debug/AddrRanges.hh"
56#include "debug/Checkpoint.hh"
67#if defined(__APPLE__) || defined(__FreeBSD__)
69#define MAP_NORESERVE 0
81 bool mmap_using_noreserve,
82 const std::string& shared_backstore,
83 bool auto_unlink_shared_backstore) :
84 _name(_name), size(0), mmapUsingNoReserve(mmap_using_noreserve),
85 sharedBackstore(shared_backstore), sharedBackstoreSize(0),
86 pageSize(sysconf(_SC_PAGE_SIZE))
93 if (mmap_using_noreserve)
94 warn(
"Not reserving swap space. May cause SIGSEGV on actual usage\n");
98 for (
const auto&
m : _memories) {
100 if (
m->isInAddrMap()) {
109 "Memory address range for %s is overlapping\n",
116 "Skipping memory %s that is not in global address map\n",
120 fatal_if(
m->getAddrRange().interleaved(),
121 "Memory %s that is not in the global address map cannot "
122 "be interleaved\n",
m->name());
129 m->isConfReported(),
m->isInAddrMap(),
142 if (!
r.second->isNull()) {
144 if (
r.first.interleaved()) {
148 if (!intlv_ranges.empty() &&
149 !intlv_ranges.back().mergesWith(
r.first)) {
153 for (
const auto&
c : curr_memories)
154 if (
f->isConfReported() !=
c->isConfReported() ||
155 f->isInAddrMap() !=
c->isInAddrMap() ||
156 f->isKvmMap() !=
c->isKvmMap())
157 fatal(
"Inconsistent flags in an interleaved "
161 f->isConfReported(),
f->isInAddrMap(),
164 intlv_ranges.clear();
165 curr_memories.clear();
167 intlv_ranges.push_back(
r.first);
168 curr_memories.push_back(
r.second);
172 r.second->isConfReported(),
173 r.second->isInAddrMap(),
174 r.second->isKvmMap());
181 if (!intlv_ranges.empty()) {
185 for (
const auto&
c : curr_memories)
186 if (
f->isConfReported() !=
c->isConfReported() ||
187 f->isInAddrMap() !=
c->isInAddrMap() ||
188 f->isKvmMap() !=
c->isKvmMap())
189 fatal(
"Inconsistent flags in an interleaved "
193 f->isConfReported(),
f->isInAddrMap(),
201 bool conf_table_reported,
bool in_addr_map,
bool kvm_map)
204 "Cannot create backing store for interleaved range %s\n",
208 DPRINTF(AddrRanges,
"Creating backing store for range %s with size %d\n",
217 map_flags = MAP_ANON | MAP_PRIVATE;
225 DPRINTF(AddrRanges,
"Sharing backing store as %s at offset %llu\n",
229 panic(
"Shared memory failed");
231 panic(
"Setting size of shared memory failed");
232 map_flags = MAP_SHARED;
238 map_flags |= MAP_NORESERVE;
241 uint8_t* pmem = (uint8_t*) mmap(NULL, range.
size(),
242 PROT_READ | PROT_WRITE,
243 map_flags, shm_fd, map_offset);
245 if (pmem == (uint8_t*) MAP_FAILED) {
247 fatal(
"Could not mmap %d bytes for range %s!\n", range.
size(),
254 conf_table_reported, in_addr_map, kvm_map,
258 for (
const auto&
m : _memories) {
259 DPRINTF(AddrRanges,
"Mapping memory %s to backing store\n",
261 m->setBackingStore(pmem);
269 munmap((
char*)
s.pmem,
s.range.size());
286 if (
r.second->isConfReported()) {
288 if (
r.first.interleaved()) {
292 if (!intlv_ranges.empty() &&
293 !intlv_ranges.back().mergesWith(
r.first)) {
294 ranges.push_back(
AddrRange(intlv_ranges));
295 intlv_ranges.clear();
297 intlv_ranges.push_back(
r.first);
300 ranges.push_back(
r.first);
307 if (!intlv_ranges.empty()) {
308 ranges.push_back(
AddrRange(intlv_ranges));
320 m->second->access(pkt);
329 m->second->functionalAccess(pkt);
341 for (
const auto&
l : locked_addrs) {
342 lal_addr.push_back(
l.addr);
343 lal_cid.push_back(
l.contextId);
354 unsigned int store_id = 0;
368 std::string filename =
369 name() +
".store" + std::to_string(store_id) +
".pmem";
370 long range_size = range.
size();
372 DPRINTF(Checkpoint,
"Serializing physical memory %s with size %d\n",
373 filename, range_size);
381 gzFile compressed_mem = gzopen(filepath.c_str(),
"wb");
382 if (compressed_mem == NULL)
383 fatal(
"Can't open physical memory checkpoint file '%s'\n",
386 uint64_t pass_size = 0;
389 for (uint64_t written = 0; written < range.
size();
390 written += pass_size) {
391 pass_size = (uint64_t)INT_MAX < (range.
size() - written) ?
392 (uint64_t)INT_MAX : (range.
size() - written);
394 if (gzwrite(compressed_mem, pmem + written,
395 (
unsigned int) pass_size) != (
int) pass_size) {
396 fatal(
"Write failed on physical memory checkpoint file '%s'\n",
403 if (gzclose(compressed_mem))
404 fatal(
"Close failed on physical memory checkpoint file '%s'\n",
418 for (
size_t i = 0;
i < lal_addr.size(); ++
i) {
419 const auto&
m =
addrMap.contains(lal_addr[
i]);
420 m->second->addLockedAddr(
LockedAddr(lal_addr[
i], lal_cid[
i]));
424 unsigned int nbr_of_stores;
427 for (
unsigned int i = 0;
i < nbr_of_stores; ++
i) {
437 const uint32_t chunk_size = 16384;
439 unsigned int store_id;
442 std::string filename;
444 std::string filepath = cp.
getCptDir() +
"/" + filename;
447 gzFile compressed_mem = gzopen(filepath.c_str(),
"rb");
448 if (compressed_mem == NULL)
449 fatal(
"Can't open physical memory checkpoint file '%s'", filename);
458 DPRINTF(Checkpoint,
"Unserializing physical memory %s with size %d\n",
459 filename, range_size);
461 if (range_size != range.
size())
462 fatal(
"Memory range size has changed! Saw %lld, expected %lld\n",
463 range_size, range.
size());
465 uint64_t curr_size = 0;
466 long* temp_page =
new long[chunk_size];
469 while (curr_size < range.
size()) {
470 bytes_read = gzread(compressed_mem, temp_page, chunk_size);
474 assert(bytes_read %
sizeof(
long) == 0);
476 for (uint32_t
x = 0;
x < bytes_read /
sizeof(long);
x++) {
479 if (*(temp_page +
x) != 0) {
480 pmem_current = (
long*)(pmem + curr_size +
x *
sizeof(
long));
481 *pmem_current = *(temp_page +
x);
484 curr_size += bytes_read;
489 if (gzclose(compressed_mem))
490 fatal(
"Close failed on physical memory checkpoint file '%s'\n",
AbstractMemory declaration.
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
AddrRange getAddrRange() const
Get address range to which this packet belongs.
An abstract memory represents a contiguous block of physical memory, with an associated address range...
Locked address class that represents a physical address and a context id.
std::vector< BackingStoreEntry > backingStore
AddrRangeList getConfAddrRanges() const
Get the memory ranges for all memories that are to be reported to the configuration table.
bool isMemAddr(Addr addr) const
Check if a physical address is within a range of a memory that is part of the global address map.
~PhysicalMemory()
Unmap all the backing store we have used.
const std::string name() const
Return the name for debugging and for creation of sections for checkpointing.
void unserializeStore(CheckpointIn &cp)
Unserialize a specific backing store, identified by a section.
std::vector< AbstractMemory * > memories
AddrRangeMap< AbstractMemory *, 1 > addrMap
void createBackingStore(AddrRange range, const std::vector< AbstractMemory * > &_memories, bool conf_table_reported, bool in_addr_map, bool kvm_map)
Create the memory region providing the backing store for a given address range that corresponds to a ...
PhysicalMemory(const PhysicalMemory &)
void unserialize(CheckpointIn &cp) override
Unserialize the memories in the system.
const bool mmapUsingNoReserve
const std::string sharedBackstore
void serializeStore(CheckpointOut &cp, unsigned int store_id, AddrRange range, uint8_t *pmem) const
Serialize a specific store.
void functionalAccess(PacketPtr pkt)
Perform an untimed memory read or write without changing anything but the memory itself.
uint64_t sharedBackstoreSize
void access(PacketPtr pkt)
Perform an untimed memory access and update all the state (e.g.
void serialize(CheckpointOut &cp) const override
Serialize all the memories in the system.
bool interleaved() const
Determine if the range is interleaved or not.
Addr size() const
Get the size of the address range.
std::string to_string() const
Get a string representation of the range.
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
#define panic(...)
This implements a cprintf based panic() function.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define fatal(...)
This implements a cprintf based fatal() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
#define UNSERIALIZE_CONTAINER(member)
const std::string getCptDir()
#define SERIALIZE_CONTAINER(member)
static std::string dir()
Get the current checkout directory name.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
std::ostream CheckpointOut
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
std::string csprintf(const char *format, const Args &...args)
void registerExitCallback(const std::function< void()> &callback)
Register an exit callback.
#define UNSERIALIZE_SCALAR(scalar)
#define SERIALIZE_SCALAR(scalar)