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:
Nikos Nikoleris
2018-05-02 14:41:22 +01:00
parent f94f70237d
commit 8100fb5f19
3 changed files with 33 additions and 11 deletions

View File

@@ -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
View File

@@ -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
View File

@@ -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:
/**