diff --git a/configs/example/cache_partitioning.py b/configs/example/cache_partitioning.py index 2e204b225c..9a363756e8 100644 --- a/configs/example/cache_partitioning.py +++ b/configs/example/cache_partitioning.py @@ -162,11 +162,13 @@ system = configSystem() # create a cache to sit between the memory and traffic gen to enforce # partitioning policies -partition_policy = generatePartPolicy(args) +part_manager = PartitionManager( + partitioning_policies=[generatePartPolicy(args)] +) system.cache = NoncoherentCache( size="64KiB", assoc=8, - partitioning_policies=[partition_policy], + partitioning_manager=part_manager, tag_latency=0, data_latency=0, response_latency=0, diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index c7fa39e2cd..b9f8d6e6b5 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -93,6 +93,7 @@ Source('fs_workload.cc', tags='arm isa') Source('regs/int.cc', tags='arm isa') Source('regs/misc.cc', tags='arm isa') Source('mmu.cc', tags='arm isa') +Source('mpam.cc', tags='arm isa') Source('nativetrace.cc', tags='arm isa') Source('pagetable.cc', tags='arm isa') Source('pauth_helpers.cc', tags='arm isa') diff --git a/src/mem/cache/tags/partitioning_policies/partition_fields_extension.cc b/src/arch/arm/mpam.cc similarity index 74% rename from src/mem/cache/tags/partitioning_policies/partition_fields_extension.cc rename to src/arch/arm/mpam.cc index bbf29a00e3..e47b4f80ad 100644 --- a/src/mem/cache/tags/partitioning_policies/partition_fields_extension.cc +++ b/src/arch/arm/mpam.cc @@ -35,55 +35,39 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "partition_fields_extension.hh" +#include "arch/arm/mpam.hh" -namespace gem5 -{ - -namespace partitioning_policy +namespace gem5::ArmISA::mpam { std::unique_ptr -PartitionFieldExtention::clone() const +PartitionFieldExtension::clone() const { - return std::make_unique(*this); + return std::make_unique(*this); } uint64_t -PartitionFieldExtention::getPartitionID() const +PartitionFieldExtension::getPartitionID() const { return this->_partitionID; } uint64_t -PartitionFieldExtention::getPartitionMonitoringID() const +PartitionFieldExtension::getPartitionMonitoringID() const { return this->_partitionMonitoringID; } void -PartitionFieldExtention::setPartitionID(uint64_t id) +PartitionFieldExtension::setPartitionID(uint64_t id) { this->_partitionID = id; } void -PartitionFieldExtention::setPartitionMonitoringID(uint64_t id) +PartitionFieldExtension::setPartitionMonitoringID(uint64_t id) { this->_partitionMonitoringID = id; } -uint64_t -readPacketPartitionID (PacketPtr pkt) -{ - // get partition_id from PartitionFieldExtention - std::shared_ptr ext = - pkt->req->getExtension(); - - // use default value if extension is not set - return (ext != nullptr) ? ext->getPartitionID() : DEFAULT_PARTITION_ID; -} - -} // namespace partitioning_policy - -} // namespace gem5 +} // namespace gem5::ArmISA::mpam diff --git a/src/mem/cache/tags/partitioning_policies/partition_fields_extension.hh b/src/arch/arm/mpam.hh similarity index 81% rename from src/mem/cache/tags/partitioning_policies/partition_fields_extension.hh rename to src/arch/arm/mpam.hh index b7b9dea16d..613a53777c 100644 --- a/src/mem/cache/tags/partitioning_policies/partition_fields_extension.hh +++ b/src/arch/arm/mpam.hh @@ -35,28 +35,25 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __MEM_CACHE_TAGS_PARTITIONING_POLICIES_FIELD_EXTENTION_HH__ -#define __MEM_CACHE_TAGS_PARTITIONING_POLICIES_FIELD_EXTENTION_HH__ +#ifndef __ARCH_ARM_MPAM_HH__ +#define __ARCH_ARM_MPAM_HH__ #include "base/extensible.hh" #include "mem/packet.hh" #include "mem/request.hh" -namespace gem5 -{ - -namespace partitioning_policy +namespace gem5::ArmISA::mpam { const uint64_t DEFAULT_PARTITION_ID = 0; const uint64_t DEFAULT_PARTITION_MONITORING_ID = 0; -class PartitionFieldExtention : public Extension +class PartitionFieldExtension : public Extension { public: std::unique_ptr clone() const override; - PartitionFieldExtention() = default; + PartitionFieldExtension() = default; /** * _partitionID getter @@ -87,16 +84,6 @@ class PartitionFieldExtention : public Extensionreq->getExtension(); + // use default value if extension is not set + return (ext != nullptr) ? ext->getPartitionID() : + ArmISA::mpam::DEFAULT_PARTITION_ID; +} + +} // namespace gem5::mpam diff --git a/src/dev/arm/mpam.hh b/src/dev/arm/mpam.hh new file mode 100644 index 0000000000..e85bca6a2e --- /dev/null +++ b/src/dev/arm/mpam.hh @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2024 Arm Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DEV_ARM_MPAM_HH__ +#define __DEV_ARM_MPAM_HH__ + +#include "mem/cache/tags/partitioning_policies/partition_manager.hh" + +namespace gem5::mpam +{ + +/** + * This class implements a simple MPAM Memory System Component (MSC) + * partitioning controller. For further info refer to: + * https://developer.arm.com/documentation/ddi0598/latest/ + */ +class MSC : public partitioning_policy::PartitionManager +{ + public: + using partitioning_policy::PartitionManager::PartitionManager; + + /** + * Helper function to retrieve PartitionID from a packet; Returns packet + * PartitionID if available or DEFAULT_PARTITION_ID if extention is not set + * @param pkt pointer to packet (PacketPtr) + * @return packet PartitionID. + */ + uint64_t readPacketPartitionID(PacketPtr pkt) const override; +}; + +} // namespace gem5::mpam + +#endif // __DEV_ARM_MPAM_HH__ diff --git a/src/mem/cache/Cache.py b/src/mem/cache/Cache.py index 874182a9f8..fdc1d8fc0f 100644 --- a/src/mem/cache/Cache.py +++ b/src/mem/cache/Cache.py @@ -111,11 +111,8 @@ class BaseCache(ClockedObject): replacement_policy = Param.BaseReplacementPolicy( LRURP(), "Replacement policy" ) - partitioning_policies = VectorParam.BasePartitioningPolicy( - [], - "Partitioning policies " - "Setting multiple policies will enforce all of them individually " - "in order", + partitioning_manager = Param.PartitionManager( + NULL, "Cache partitioning manager" ) compressor = Param.BaseCacheCompressor(NULL, "Cache compressor.") diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index 095dea5e63..df0243a0fb 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -58,7 +58,7 @@ #include "mem/cache/prefetch/base.hh" #include "mem/cache/queue_entry.hh" #include "mem/cache/tags/compressed_tags.hh" -#include "mem/cache/tags/partitioning_policies/partition_fields_extension.hh" +#include "mem/cache/tags/partitioning_policies/partition_manager.hh" #include "mem/cache/tags/super_blk.hh" #include "params/BaseCache.hh" #include "params/WriteAllocator.hh" @@ -87,6 +87,7 @@ BaseCache::BaseCache(const BaseCacheParams &p, unsigned blk_size) writeBuffer("write buffer", p.write_buffers, p.mshrs, p.name), tags(p.tags), compressor(p.compressor), + partitionManager(p.partitioning_manager), prefetcher(p.prefetcher), writeAllocator(p.write_allocator), writebackClean(p.writeback_clean), @@ -1642,7 +1643,8 @@ BaseCache::allocateBlock(const PacketPtr pkt, PacketList &writebacks) } // get partitionId from Packet - const auto partition_id = partitioning_policy::readPacketPartitionID(pkt); + const auto partition_id = partitionManager ? + partitionManager->readPacketPartitionID(pkt) : 0; // Find replacement victim std::vector evict_blks; CacheBlk *victim = tags->findVictim(addr, is_secure, blk_size_bits, diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh index c2d9bc8a7b..af440e8b1e 100644 --- a/src/mem/cache/base.hh +++ b/src/mem/cache/base.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, 2015-2016, 2018-2019, 2023 ARM Limited + * Copyright (c) 2012-2013, 2015-2016, 2018-2019, 2023-2024 Arm Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -84,6 +84,10 @@ namespace prefetch { class Base; } +namespace partitioning_policy +{ + class PartitionManager; +} class MSHR; class RequestPort; class QueueEntry; @@ -351,6 +355,9 @@ class BaseCache : public ClockedObject /** Compression method being used. */ compression::Base* compressor; + /** Partitioning manager */ + partitioning_policy::PartitionManager* partitionManager; + /** Prefetcher */ prefetch::Base *prefetcher; diff --git a/src/mem/cache/tags/Tags.py b/src/mem/cache/tags/Tags.py index 3dbd526b35..4c159f8e20 100644 --- a/src/mem/cache/tags/Tags.py +++ b/src/mem/cache/tags/Tags.py @@ -75,8 +75,8 @@ class BaseTags(ClockedObject): SetAssociative(), "Indexing policy" ) - partitioning_policies = VectorParam.BasePartitioningPolicy( - Parent.partitioning_policies, "Partitioning policies" + partitioning_manager = Param.PartitionManager( + Parent.partitioning_manager, "Cache partitioning manager" ) # Set the indexing entry size as the block size diff --git a/src/mem/cache/tags/base.cc b/src/mem/cache/tags/base.cc index c7e529ef0c..ca6284cf34 100644 --- a/src/mem/cache/tags/base.cc +++ b/src/mem/cache/tags/base.cc @@ -50,7 +50,7 @@ #include "base/types.hh" #include "mem/cache/replacement_policies/replaceable_entry.hh" #include "mem/cache/tags/indexing_policies/base.hh" -#include "mem/cache/tags/partitioning_policies/partition_fields_extension.hh" +#include "mem/cache/tags/partitioning_policies/partition_manager.hh" #include "mem/request.hh" #include "sim/core.hh" #include "sim/sim_exit.hh" @@ -63,7 +63,7 @@ BaseTags::BaseTags(const Params &p) : ClockedObject(p), blkSize(p.block_size), blkMask(blkSize - 1), size(p.size), lookupLatency(p.tag_latency), system(p.system), indexingPolicy(p.indexing_policy), - partitioningPolicies(p.partitioning_policies), + partitionManager(p.partitioning_manager), warmupBound((p.warmup_percentage/100.0) * (p.size / p.block_size)), warmedUp(false), numBlocks(p.size / p.block_size), dataBlks(new uint8_t[p.size]), // Allocate data storage in one big chunk @@ -114,7 +114,8 @@ BaseTags::insertBlock(const PacketPtr pkt, CacheBlk *blk) stats.occupancies[requestor_id]++; // Insert block with tag, src requestor id, task id and PartitionId - const auto partition_id = partitioning_policy::readPacketPartitionID(pkt); + const auto partition_id = partitionManager ? + partitionManager->readPacketPartitionID(pkt) : 0; blk->insert(extractTag(pkt->getAddr()), pkt->isSecure(), requestor_id, pkt->req->taskId(), partition_id); diff --git a/src/mem/cache/tags/base.hh b/src/mem/cache/tags/base.hh index 307159ae1d..d700418937 100644 --- a/src/mem/cache/tags/base.hh +++ b/src/mem/cache/tags/base.hh @@ -56,7 +56,6 @@ #include "base/statistics.hh" #include "base/types.hh" #include "mem/cache/cache_blk.hh" -#include "mem/cache/tags/partitioning_policies/base_pp.hh" #include "mem/packet.hh" #include "params/BaseTags.hh" #include "sim/clocked_object.hh" @@ -89,9 +88,8 @@ class BaseTags : public ClockedObject /** Indexing policy */ BaseIndexingPolicy *indexingPolicy; - /** Partitioning policies */ - std::vector - partitioningPolicies; + /** Partitioning manager */ + partitioning_policy::PartitionManager *partitionManager; /** * The number of tags that need to be touched to meet the warmup diff --git a/src/mem/cache/tags/base_set_assoc.cc b/src/mem/cache/tags/base_set_assoc.cc index 1973967d1b..79bcb1eff5 100644 --- a/src/mem/cache/tags/base_set_assoc.cc +++ b/src/mem/cache/tags/base_set_assoc.cc @@ -89,8 +89,9 @@ void BaseSetAssoc::invalidate(CacheBlk *blk) { // Notify partitioning policies of release of ownership - for (auto partitioning_policy : partitioningPolicies) - partitioning_policy->notifyRelease(blk->getPartitionId()); + if (partitionManager) { + partitionManager->notifyRelease(blk->getPartitionId()); + } BaseTags::invalidate(blk); diff --git a/src/mem/cache/tags/base_set_assoc.hh b/src/mem/cache/tags/base_set_assoc.hh index db5fe605a7..b68238e449 100644 --- a/src/mem/cache/tags/base_set_assoc.hh +++ b/src/mem/cache/tags/base_set_assoc.hh @@ -59,7 +59,7 @@ #include "mem/cache/replacement_policies/replaceable_entry.hh" #include "mem/cache/tags/base.hh" #include "mem/cache/tags/indexing_policies/base.hh" -#include "mem/cache/tags/partitioning_policies/partition_fields_extension.hh" +#include "mem/cache/tags/partitioning_policies/partition_manager.hh" #include "mem/packet.hh" #include "params/BaseSetAssoc.hh" @@ -177,8 +177,9 @@ class BaseSetAssoc : public BaseTags indexingPolicy->getPossibleEntries(addr); // Filter entries based on PartitionID - for (auto partitioning_policy : partitioningPolicies) - partitioning_policy->filterByPartition(entries, partition_id); + if (partitionManager) { + partitionManager->filterByPartition(entries, partition_id); + } // Choose replacement victim from replacement candidates CacheBlk* victim = entries.empty() ? nullptr : @@ -204,12 +205,9 @@ class BaseSetAssoc : public BaseTags // Increment tag counter stats.tagsInUse++; - // Notify partitioning policies of acquisition of ownership - for (auto & partitioning_policy : partitioningPolicies) { - // get partitionId from Packet - const auto partitionId = - partitioning_policy::readPacketPartitionID(pkt); - partitioning_policy->notifyAcquire(partitionId); + if (partitionManager) { + auto partition_id = partitionManager->readPacketPartitionID(pkt); + partitionManager->notifyAcquire(partition_id); } // Update replacement policy diff --git a/src/mem/cache/tags/compressed_tags.cc b/src/mem/cache/tags/compressed_tags.cc index 96afd635aa..352ac8a3ad 100644 --- a/src/mem/cache/tags/compressed_tags.cc +++ b/src/mem/cache/tags/compressed_tags.cc @@ -50,6 +50,7 @@ #include "mem/cache/replacement_policies/base.hh" #include "mem/cache/replacement_policies/replaceable_entry.hh" #include "mem/cache/tags/indexing_policies/base.hh" +#include "mem/cache/tags/partitioning_policies/partition_manager.hh" #include "mem/packet.hh" #include "params/CompressedTags.hh" @@ -124,8 +125,8 @@ CompressedTags::findVictim(Addr addr, const bool is_secure, indexingPolicy->getPossibleEntries(addr); // Filter entries based on PartitionID - for (auto partitioning_policy : partitioningPolicies){ - partitioning_policy->filterByPartition(superblock_entries, + if (partitionManager){ + partitionManager->filterByPartition(superblock_entries, partition_id); } diff --git a/src/mem/cache/tags/fa_lru.cc b/src/mem/cache/tags/fa_lru.cc index 1937ec2b25..626f419015 100644 --- a/src/mem/cache/tags/fa_lru.cc +++ b/src/mem/cache/tags/fa_lru.cc @@ -75,7 +75,7 @@ FALRU::FALRU(const Params &p) blkSize); if (!isPowerOf2(size)) fatal("Cache Size must be power of 2 for now"); - if (this->partitioningPolicies.size() != 0) + if (partitionManager) fatal("Cannot use Cache Partitioning Policies with FALRU"); blks = new FALRUBlk[numBlocks]; diff --git a/src/mem/cache/tags/partitioning_policies/PartitioningPolicies.py b/src/mem/cache/tags/partitioning_policies/PartitioningPolicies.py index 74ef6c5113..a441813f8c 100644 --- a/src/mem/cache/tags/partitioning_policies/PartitioningPolicies.py +++ b/src/mem/cache/tags/partitioning_policies/PartitioningPolicies.py @@ -1,5 +1,14 @@ -# Copyright (c) 2024 ARM Limited -# All rights reserved. +# Copyright (c) 2024 Arm Limited +# All rights reserved +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -32,6 +41,19 @@ from m5.proxy import Parent from m5.SimObject import SimObject +class PartitionManager(SimObject): + type = "PartitionManager" + cxx_header = "mem/cache/tags/partitioning_policies/partition_manager.hh" + cxx_class = "gem5::partitioning_policy::PartitionManager" + + partitioning_policies = VectorParam.BasePartitioningPolicy( + [], + "Partitioning policies " + "Setting multiple policies will enforce all of them individually " + "in order", + ) + + class BasePartitioningPolicy(SimObject): type = "BasePartitioningPolicy" cxx_header = "mem/cache/tags/partitioning_policies/base_pp.hh" diff --git a/src/mem/cache/tags/partitioning_policies/SConscript b/src/mem/cache/tags/partitioning_policies/SConscript index 37c75f4de6..901ef03569 100644 --- a/src/mem/cache/tags/partitioning_policies/SConscript +++ b/src/mem/cache/tags/partitioning_policies/SConscript @@ -38,6 +38,7 @@ Import('*') SimObject('PartitioningPolicies.py', sim_objects=[ + 'PartitionManager', 'BasePartitioningPolicy', 'MaxCapacityPartitioningPolicy', 'WayPolicyAllocation', @@ -48,4 +49,4 @@ Source('base_pp.cc') Source('max_capacity_pp.cc') Source('way_allocation.cc') Source('way_pp.cc') -Source('partition_fields_extension.cc') +Source('partition_manager.cc') diff --git a/src/mem/cache/tags/partitioning_policies/base_pp.hh b/src/mem/cache/tags/partitioning_policies/base_pp.hh index 781e2af7d9..5ea160c335 100644 --- a/src/mem/cache/tags/partitioning_policies/base_pp.hh +++ b/src/mem/cache/tags/partitioning_policies/base_pp.hh @@ -54,12 +54,11 @@ namespace partitioning_policy /** * A Partitioning Policy is a cache partitioning mechanism that limits the * cache block allocations in a cache based on a PartitionID identifier. This - * identifier may be set to any upstream memory request by attaching a - * PartitionFieldExtention to it as so: + * identifier may be set to any upstream memory request by attaching the + * PartitionID to it. The way the partition ID is attached/extracted + * from the request depends on the partitioning manager. * - * std::shared_ptr ext(PartitionFieldExtention); - * ext->setPartitionID(PartitionID); - * req->setExtension(ext); + * See the use of the PartitionFieldExtension in Arm as an example. * * When partitioning policies are in place, the allocatable cache blocks for * this memory request will be filtered based on its PartitionID. diff --git a/src/mem/cache/tags/partitioning_policies/partition_manager.cc b/src/mem/cache/tags/partitioning_policies/partition_manager.cc new file mode 100644 index 0000000000..109a43bba7 --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/partition_manager.cc @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2024 Arm Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mem/cache/tags/partitioning_policies/partition_manager.hh" + +#include "mem/cache/tags/partitioning_policies/base_pp.hh" + +namespace gem5 +{ + +namespace partitioning_policy +{ + +PartitionManager::PartitionManager(const Params &p) + : SimObject(p), + partitioningPolicies(p.partitioning_policies) +{} + +void +PartitionManager::notifyAcquire(uint64_t partition_id) +{ + // Notify partitioning policies of acquisition of ownership + for (auto & partitioning_policy : partitioningPolicies) { + // get partitionId from Packet + partitioning_policy->notifyAcquire(partition_id); + } +} + +void +PartitionManager::notifyRelease(uint64_t partition_id) +{ + // Notify partitioning policies of release of ownership + for (auto partitioning_policy : partitioningPolicies) { + partitioning_policy->notifyRelease(partition_id); + } +} + +void +PartitionManager::filterByPartition( + std::vector &entries, + const uint64_t partition_id) const +{ + // Filter entries based on PartitionID + for (auto partitioning_policy : partitioningPolicies) { + partitioning_policy->filterByPartition(entries, partition_id); + } +} + +} // namespace partitioning_policy + +} // namespace gem5 diff --git a/src/mem/cache/tags/partitioning_policies/partition_manager.hh b/src/mem/cache/tags/partitioning_policies/partition_manager.hh new file mode 100644 index 0000000000..ca9436a2cf --- /dev/null +++ b/src/mem/cache/tags/partitioning_policies/partition_manager.hh @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2024 Arm Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __MEM_CACHE_TAGS_PARTITIONING_MANAGER_HH__ +#define __MEM_CACHE_TAGS_PARTITIONING_MANAGER_HH__ + +#include "mem/packet.hh" +#include "params/PartitionManager.hh" +#include "sim/sim_object.hh" + +namespace gem5 +{ + +class ReplaceableEntry; + +namespace partitioning_policy +{ + +class BasePartitioningPolicy; + +class PartitionManager : public SimObject +{ + public: + PARAMS(PartitionManager); + PartitionManager(const Params &p); + + /** + * PartitionManager interface to retrieve PartitionID from a packet; + * This base implementation returns zero by default. + * + * @param pkt pointer to packet (PacketPtr) + * @return packet PartitionID. + */ + virtual uint64_t + readPacketPartitionID(PacketPtr pkt) const + { + return 0; + }; + + /** + * Notify of acquisition of ownership of a cache line + * @param partition_id PartitionID of the upstream memory request + */ + void notifyAcquire(uint64_t partition_id); + + void notifyRelease(uint64_t partition_id); + + void filterByPartition(std::vector &entries, + const uint64_t partition_id) const; + + protected: + /** Partitioning policies */ + std::vector + partitioningPolicies; +}; + +} // namespace partitioning_policy + +} // namespace gem5 + +#endif // __MEM_CACHE_TAGS_PARTITIONING_MANAGER_HH__ diff --git a/src/mem/cache/tags/sector_tags.cc b/src/mem/cache/tags/sector_tags.cc index 73eaa46703..4f0b39286c 100644 --- a/src/mem/cache/tags/sector_tags.cc +++ b/src/mem/cache/tags/sector_tags.cc @@ -55,6 +55,7 @@ #include "mem/cache/replacement_policies/base.hh" #include "mem/cache/replacement_policies/replaceable_entry.hh" #include "mem/cache/tags/indexing_policies/base.hh" +#include "mem/cache/tags/partitioning_policies/partition_manager.hh" namespace gem5 { @@ -76,7 +77,7 @@ SectorTags::SectorTags(const SectorTagsParams &p) "Block size must be at least 4 and a power of 2"); fatal_if(!isPowerOf2(numBlocksPerSector), "# of blocks per sector must be non-zero and a power of 2"); - warn_if((p.partitioning_policies.size() > 0), + warn_if(partitionManager, "Using cache partitioning policies with sector and/or compressed " "tags is not fully tested."); } @@ -296,8 +297,8 @@ SectorTags::findVictim(Addr addr, const bool is_secure, const std::size_t size, indexingPolicy->getPossibleEntries(addr); // Filter entries based on PartitionID - for (auto partitioning_policy : partitioningPolicies) - partitioning_policy->filterByPartition(sector_entries, partition_id); + if (partitionManager) + partitionManager->filterByPartition(sector_entries, partition_id); // Check if the sector this address belongs to has been allocated Addr tag = extractTag(addr);