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.
This commit is contained in:
Andreas Hansson 2016-02-10 04:08:24 -05:00
parent 986214f181
commit f84ee031cc

View file

@ -1011,8 +1011,6 @@ Cache::recvAtomic(PacketPtr pkt)
{ {
// We are in atomic mode so we pay just for lookupLatency here. // We are in atomic mode so we pay just for lookupLatency here.
Cycles lat = lookupLatency; Cycles lat = lookupLatency;
// @TODO: make this a parameter
bool last_level_cache = false;
// Forward the request if the system is in cache bypass mode. // Forward the request if the system is in cache bypass mode.
if (system->bypassCaches()) if (system->bypassCaches())
@ -1020,30 +1018,18 @@ Cache::recvAtomic(PacketPtr pkt)
promoteWholeLineWrites(pkt); promoteWholeLineWrites(pkt);
// follow the same flow as in recvTimingReq, and check if a cache
// above us is responding
if (pkt->cacheResponding()) { if (pkt->cacheResponding()) {
// have to invalidate ourselves and any lower caches even if DPRINTF(Cache, "Cache above responding to %#llx (%s): "
// upper cache will be responding "not responding\n",
if (pkt->isInvalidate()) { pkt->getAddr(), pkt->isSecure() ? "s" : "ns");
CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
if (blk && blk->isValid()) { // if a cache is responding, and it had the line in Owned
tags->invalidate(blk); // rather than Modified state, we need to invalidate any
blk->invalidate(); // copies that are not on the same path to memory
DPRINTF(Cache, "Other cache responding to %s on %#llx (%s):" if (pkt->needsWritable() && !pkt->responderHadWritable()) {
" invalidating\n", lat += ticksToCycles(memSidePort->sendAtomic(pkt));
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());
} }
return lat * clockPeriod(); return lat * clockPeriod();