summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2016-02-10 04:08:24 -0500
committerAndreas Hansson <andreas.hansson@arm.com>2016-02-10 04:08:24 -0500
commitf84ee031ccdb63d016c6f55b578085a2e5af4a4b (patch)
tree3c494751302b00722e189fc9e9a2aabd76dfb492
parent986214f1816be2dc6f3758c4b80d8fbc945495b0 (diff)
downloadgem5-f84ee031ccdb63d016c6f55b578085a2e5af4a4b.tar.xz
mem: Align cache behaviour in atomic when upstream is responding
Adopt the same flow as in timing mode, where the caches on the path to memory get to keep the line (if present), and we use the responderHadWritable flag to determine if we need to forward the (invalidating) packet or not.
-rw-r--r--src/mem/cache/cache.cc36
1 files changed, 11 insertions, 25 deletions
diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc
index 7a5d22ef0..189fd4cab 100644
--- a/src/mem/cache/cache.cc
+++ b/src/mem/cache/cache.cc
@@ -1011,8 +1011,6 @@ Cache::recvAtomic(PacketPtr pkt)
{
// We are in atomic mode so we pay just for lookupLatency here.
Cycles lat = lookupLatency;
- // @TODO: make this a parameter
- bool last_level_cache = false;
// Forward the request if the system is in cache bypass mode.
if (system->bypassCaches())
@@ -1020,30 +1018,18 @@ Cache::recvAtomic(PacketPtr pkt)
promoteWholeLineWrites(pkt);
+ // follow the same flow as in recvTimingReq, and check if a cache
+ // above us is responding
if (pkt->cacheResponding()) {
- // have to invalidate ourselves and any lower caches even if
- // upper cache will be responding
- if (pkt->isInvalidate()) {
- CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
- if (blk && blk->isValid()) {
- tags->invalidate(blk);
- blk->invalidate();
- DPRINTF(Cache, "Other cache responding to %s on %#llx (%s):"
- " invalidating\n",
- pkt->cmdString(), pkt->getAddr(),
- pkt->isSecure() ? "s" : "ns");
- }
- if (!last_level_cache) {
- DPRINTF(Cache, "Other cache responding to %s on %#llx (%s):"
- " forwarding\n",
- pkt->cmdString(), pkt->getAddr(),
- pkt->isSecure() ? "s" : "ns");
- lat += ticksToCycles(memSidePort->sendAtomic(pkt));
- }
- } else {
- DPRINTF(Cache, "Other cache responding to %s on %#llx: "
- "not responding\n",
- pkt->cmdString(), pkt->getAddr());
+ DPRINTF(Cache, "Cache above responding to %#llx (%s): "
+ "not responding\n",
+ pkt->getAddr(), pkt->isSecure() ? "s" : "ns");
+
+ // if a cache is responding, and it had the line in Owned
+ // rather than Modified state, we need to invalidate any
+ // copies that are not on the same path to memory
+ if (pkt->needsWritable() && !pkt->responderHadWritable()) {
+ lat += ticksToCycles(memSidePort->sendAtomic(pkt));
}
return lat * clockPeriod();