From 61a6ec7b7160332c0ef88e9511cc22f1a30719c3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 11 Sep 2021 06:06:28 -0700 Subject: [PATCH] sim: Move serialization logic for MemPools out of System. And move it into the MemPools class itself. The MemPools class should be self contained, and be able to manage its own state. That should not be the responsibility of another containing class. Change-Id: Ib0bf70b57e92698f15bea0cc217dd98ee816d57b Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/50340 Tested-by: kokoro Reviewed-by: Giacomo Travaglini Maintainer: Giacomo Travaglini --- src/sim/mem_pool.cc | 18 ++++++++++++ src/sim/mem_pool.hh | 16 +++++++---- src/sim/system.cc | 30 +++++++++----------- util/cpt_upgraders/mempool-sections.py | 39 ++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 22 deletions(-) create mode 100644 util/cpt_upgraders/mempool-sections.py diff --git a/src/sim/mem_pool.cc b/src/sim/mem_pool.cc index bde3e67b91..a7dc7c4631 100644 --- a/src/sim/mem_pool.cc +++ b/src/sim/mem_pool.cc @@ -124,4 +124,22 @@ MemPool::allocate(Addr npages) return return_addr; } +void +MemPool::serialize(CheckpointOut &cp) const +{ + paramOut(cp, "page_shift", pageShift); + paramOut(cp, "start_page", startPageNum); + paramOut(cp, "free_page_num", freePageNum); + paramOut(cp, "total_pages", _totalPages); +} + +void +MemPool::unserialize(CheckpointIn &cp) +{ + paramIn(cp, "page_shift", pageShift); + paramIn(cp, "start_page", startPageNum); + paramIn(cp, "free_page_num", freePageNum); + paramIn(cp, "total_pages", _totalPages); +} + } // namespace gem5 diff --git a/src/sim/mem_pool.hh b/src/sim/mem_pool.hh index 3cba3b6987..0b681cd051 100644 --- a/src/sim/mem_pool.hh +++ b/src/sim/mem_pool.hh @@ -35,6 +35,7 @@ #define __MEM_POOL_HH__ #include "base/types.hh" +#include "sim/serialize.hh" namespace gem5 { @@ -42,21 +43,23 @@ namespace gem5 class System; /** Class for handling allocation of physical pages in SE mode. */ -class MemPool +class MemPool : public Serializable { private: - Addr pageShift; + Addr pageShift = 0; /** Start page of pool. */ - Counter startPageNum; + Counter startPageNum = 0; /** Page number of free memory. */ - Counter freePageNum; + Counter freePageNum = 0; /** The size of the pool, in number of pages. */ - Counter _totalPages; + Counter _totalPages = 0; public: + MemPool() {} + MemPool(Addr page_shift, Addr ptr, Addr limit); Counter startPage() const; @@ -74,6 +77,9 @@ class MemPool Addr totalBytes() const; Addr allocate(Addr npages); + + void serialize(CheckpointOut &cp) const override; + void unserialize(CheckpointIn &cp) override; }; } // namespace gem5 diff --git a/src/sim/system.cc b/src/sim/system.cc index 225262a4ab..5196c7183a 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -44,6 +44,7 @@ #include #include "base/compiler.hh" +#include "base/cprintf.hh" #include "base/loader/object_file.hh" #include "base/loader/symtab.hh" #include "base/str.hh" @@ -68,6 +69,7 @@ #include "sim/debug.hh" #include "sim/full_system.hh" #include "sim/redirect_path.hh" +#include "sim/serialize_handlers.hh" namespace gem5 { @@ -430,16 +432,11 @@ System::serialize(CheckpointOut &cp) const paramOut(cp, csprintf("quiesceEndTick_%d", id), when); } - std::vector ptrs; - std::vector limits; + int num_mem_pools = memPools.size(); + SERIALIZE_SCALAR(num_mem_pools); - for (const auto& memPool : memPools) { - ptrs.push_back(memPool.freePageAddr()); - limits.push_back(memPool.totalBytes() + memPool.startAddr()); - } - - SERIALIZE_CONTAINER(ptrs); - SERIALIZE_CONTAINER(limits); + for (int i = 0; i < num_mem_pools; i++) + memPools[i].serializeSection(cp, csprintf("memPool%d", i)); // also serialize the memories in the system physmem.serializeSection(cp, "physmem"); @@ -461,15 +458,14 @@ System::unserialize(CheckpointIn &cp) # endif } - std::vector ptrs; - std::vector limits; + int num_mem_pools = 0; + UNSERIALIZE_SCALAR(num_mem_pools); - UNSERIALIZE_CONTAINER(ptrs); - UNSERIALIZE_CONTAINER(limits); - - assert(ptrs.size() == limits.size()); - for (size_t i = 0; i < ptrs.size(); i++) - memPools.emplace_back(getPageShift(), ptrs[i], limits[i]); + for (int i = 0; i < num_mem_pools; i++) { + MemPool pool; + pool.unserializeSection(cp, csprintf("memPool%d", i)); + memPools.push_back(pool); + } // also unserialize the memories in the system physmem.unserializeSection(cp, "physmem"); diff --git a/util/cpt_upgraders/mempool-sections.py b/util/cpt_upgraders/mempool-sections.py new file mode 100644 index 0000000000..8b0fd2a56b --- /dev/null +++ b/util/cpt_upgraders/mempool-sections.py @@ -0,0 +1,39 @@ +# This upgrader moves memory pool attributes from a vector of pointers to the +# next free page and a vector of the limit of each pool to sections which each +# represent one pool and which hold the page shift amount, the next free page, +# and the total pages in the pool. +def upgrader(cpt): + systems = {} + for sec in cpt.sections(): + ptrs = cpt.get(sec, 'ptrs', fallback=None) + limits = cpt.get(sec, 'limits', fallback=None) + + if ptrs and limits: + systems[sec] = ptrs, limits + + for sec, (ptrs, limits) in systems.items(): + + ptrs = list(map(int, ptrs.split())) + limits = list(map(int, limits.split())) + + if len(ptrs) != len(limits): + print( + f"'{sec}ptrs' and '{limits}limits' were not the same length!") + + cpt.set(sec, 'num_mem_pools', str(len(ptrs))) + + cpt.remove_option(sec, 'ptrs') + cpt.remove_option(sec, 'limits') + + # Assume the page shift is 12, for a 4KiB page. + page_shift = 12 + + for idx, (ptr, limit) in enumerate(zip(ptrs, limits)): + new_sec = f'{sec}.memPool{idx}' + cpt.add_section(new_sec) + cpt.set(new_sec, 'page_shift', str(page_shift)) + # Since there's no way to tell where the pool actually started, + # just assume it started wherever it is right now. + cpt.set(new_sec, 'start_page', str(ptr >> page_shift)) + cpt.set(new_sec, 'free_page_num', str(ptr >> page_shift)) + cpt.set(new_sec, 'total_pages', str((limit - ptr) >> page_shift))