From 8100fb5f19b09a93c1f3e3e8533322e1fa73e6d3 Mon Sep 17 00:00:00 2001 From: Nikos Nikoleris Date: Wed, 2 May 2018 14:41:22 +0100 Subject: mem-cache: Determine if an MSHR has requests from another cache To decide whether we allocate upon receiving a response we need to determine if any of the currently serviced requests (non-deferred targets) is comming from another cache. This change adds support for tracking this information in the MSHR. Change-Id: If1db93c12b6af5813b91b9d6b6e5e196d327f038 Reviewed-on: https://gem5-review.googlesource.com/10422 Reviewed-by: Jason Lowe-Power Maintainer: Nikos Nikoleris --- src/mem/cache/cache.cc | 7 +------ src/mem/cache/mshr.cc | 12 +++++++++--- src/mem/cache/mshr.hh | 25 +++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc index 73c7e1956..e9aec499a 100644 --- a/src/mem/cache/cache.cc +++ b/src/mem/cache/cache.cc @@ -1415,7 +1415,6 @@ Cache::recvTimingResp(PacketPtr pkt) // First offset for critical word first calculations int initial_offset = initial_tgt->pkt->getOffset(blkSize); - bool from_cache = false; MSHR::TargetList targets = mshr->extractServiceableTargets(pkt); for (auto &target: targets) { Packet *tgt_pkt = target.pkt; @@ -1437,10 +1436,6 @@ Cache::recvTimingResp(PacketPtr pkt) break; // skip response } - // keep track of whether we have responded to another - // cache - from_cache = from_cache || tgt_pkt->fromCache(); - // unlike the other packet flows, where data is found in other // caches or memory and brought back, write-line requests always // have the data right away, so the above check for "is fill?" @@ -1572,7 +1567,7 @@ Cache::recvTimingResp(PacketPtr pkt) } } - maintainClusivity(from_cache, blk); + maintainClusivity(targets.hasFromCache, blk); if (blk && blk->isValid()) { // an invalidate response stemming from a write line request diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc index cc26b5651..4f170e6b3 100644 --- a/src/mem/cache/mshr.cc +++ b/src/mem/cache/mshr.cc @@ -68,7 +68,8 @@ MSHR::MSHR() : downstreamPending(false), } MSHR::TargetList::TargetList() - : needsWritable(false), hasUpgrade(false), allocOnFill(false) + : needsWritable(false), hasUpgrade(false), allocOnFill(false), + hasFromCache(false) {} @@ -91,6 +92,10 @@ MSHR::TargetList::updateFlags(PacketPtr pkt, Target::Source source, // potentially re-evaluate whether we should allocate on a fill or // not allocOnFill = allocOnFill || alloc_on_fill; + + if (source != Target::FromPrefetcher) { + hasFromCache = hasFromCache || pkt->fromCache(); + } } } @@ -590,7 +595,7 @@ MSHR::sendPacket(Cache &cache) void MSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const { - ccprintf(os, "%s[%#llx:%#llx](%s) %s %s %s state: %s %s %s %s %s\n", + ccprintf(os, "%s[%#llx:%#llx](%s) %s %s %s state: %s %s %s %s %s %s\n", prefix, blkAddr, blkAddr + blkSize - 1, isSecure ? "s" : "ns", isForward ? "Forward" : "", @@ -600,7 +605,8 @@ MSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const inService ? "InSvc" : "", downstreamPending ? "DwnPend" : "", postInvalidate ? "PostInv" : "", - postDowngrade ? "PostDowngr" : ""); + postDowngrade ? "PostDowngr" : "", + hasFromCache() ? "HasFromCache" : ""); if (!targets.empty()) { ccprintf(os, "%s Targets:\n", prefix); diff --git a/src/mem/cache/mshr.hh b/src/mem/cache/mshr.hh index 5fe0fb92d..b4bf33a4f 100644 --- a/src/mem/cache/mshr.hh +++ b/src/mem/cache/mshr.hh @@ -162,6 +162,11 @@ class MSHR : public QueueEntry, public Printable bool hasUpgrade; /** Set when the response should allocate on fill */ bool allocOnFill; + /** + * Determine whether there was at least one non-snooping + * target coming from another cache. + */ + bool hasFromCache; TargetList(); @@ -176,7 +181,12 @@ class MSHR : public QueueEntry, public Printable void updateFlags(PacketPtr pkt, Target::Source source, bool alloc_on_fill); - void resetFlags() { needsWritable = hasUpgrade = allocOnFill = false; } + void resetFlags() { + needsWritable = false; + hasUpgrade = false; + allocOnFill = false; + hasFromCache = false; + } /** * Goes through the list of targets and uses them to populate @@ -191,7 +201,8 @@ class MSHR : public QueueEntry, public Printable * values. */ bool isReset() const { - return !needsWritable && !hasUpgrade && !allocOnFill; + return !needsWritable && !hasUpgrade && !allocOnFill && + !hasFromCache; } /** @@ -257,6 +268,16 @@ class MSHR : public QueueEntry, public Printable bool allocOnFill() const { return targets.allocOnFill; } + + /** + * Determine if there are non-deferred requests from other caches + * + * @return true if any of the targets is from another cache + */ + bool hasFromCache() const { + return targets.hasFromCache; + } + private: /** -- cgit v1.2.3