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 <jason@lowepower.com> Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
This commit is contained in:
7
src/mem/cache/cache.cc
vendored
7
src/mem/cache/cache.cc
vendored
@@ -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
|
||||
|
||||
12
src/mem/cache/mshr.cc
vendored
12
src/mem/cache/mshr.cc
vendored
@@ -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);
|
||||
|
||||
25
src/mem/cache/mshr.hh
vendored
25
src/mem/cache/mshr.hh
vendored
@@ -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:
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user