From a15b713cba52d9d4d2c1204fef050fb3856ca33e Mon Sep 17 00:00:00 2001 From: Mitch Hayenga Date: Fri, 9 May 2014 18:58:46 -0400 Subject: mem: Squash prefetch requests from downstream caches This patch squashes prefetch requests from downstream caches, so that they do not steal cachelines away from caches closer to the cpu. It was originally coded by Mitch Hayenga and modified by Aasheesh Kolli. --- src/mem/cache/cache_impl.hh | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index e8e1876a0..00ba0d24f 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -1394,6 +1394,12 @@ Cache::handleSnoop(PacketPtr pkt, BlkType *blk, if (snoopPkt.sharedAsserted()) { pkt->assertShared(); } + // If this request is a prefetch and an + // upper level squashes the prefetch request, + // make sure to propogate the squash to the requester. + if (snoopPkt.prefetchSquashed()) { + pkt->setPrefetchSquashed(); + } } else { cpuSidePort->sendAtomicSnoop(pkt); if (!alreadyResponded && pkt->memInhibitAsserted()) { @@ -1420,6 +1426,17 @@ Cache::handleSnoop(PacketPtr pkt, BlkType *blk, bool respond = blk->isDirty() && pkt->needsResponse(); bool have_exclusive = blk->isWritable(); + // Invalidate any prefetch's from below that would strip write permissions + // MemCmd::HardPFReq is only observed by upstream caches. After missing + // above and in it's own cache, a new MemCmd::ReadReq is created that + // downstream caches observe. + if (pkt->cmd == MemCmd::HardPFReq) { + DPRINTF(Cache, "Squashing prefetch from lower cache %#x\n", + pkt->getAddr()); + pkt->setPrefetchSquashed(); + return; + } + if (pkt->isRead() && !invalidate) { assert(!needs_exclusive); pkt->assertShared(); @@ -1503,6 +1520,14 @@ Cache::recvTimingSnoopReq(PacketPtr pkt) Addr blk_addr = blockAlign(pkt->getAddr()); MSHR *mshr = mshrQueue.findMatch(blk_addr, is_secure); + // Squash any prefetch requests from below on MSHR hits + if (mshr && pkt->cmd == MemCmd::HardPFReq) { + DPRINTF(Cache, "Squashing prefetch from lower cache on mshr hit %#x\n", + pkt->getAddr()); + pkt->setPrefetchSquashed(); + return; + } + // Let the MSHR itself track the snoop and decide whether we want // to go ahead and do the regular cache snoop if (mshr && mshr->handleSnoop(pkt, order++)) { @@ -1730,6 +1755,20 @@ Cache::getTimingPacket() snoop_pkt.senderState = mshr; cpuSidePort->sendTimingSnoopReq(&snoop_pkt); + // Check to see if the prefetch was squashed by an upper cache + if (snoop_pkt.prefetchSquashed()) { + DPRINTF(Cache, "Prefetch squashed by upper cache. " + "Deallocating mshr target %#x.\n", mshr->addr); + + // Deallocate the mshr target + if (mshr->queue->forceDeallocateTarget(mshr)) { + // Clear block if this deallocation resulted freed an + // mshr when all had previously been utilized + clearBlocked((BlockedCause)(mshr->queue->index)); + } + return NULL; + } + if (snoop_pkt.memInhibitAsserted()) { markInService(mshr, &snoop_pkt); DPRINTF(Cache, "Upward snoop of prefetch for addr" -- cgit v1.2.3