summaryrefslogtreecommitdiff
path: root/src/mem/abstract_mem.cc
diff options
context:
space:
mode:
authorAli Jafri <ali.jafri@arm.com>2015-07-03 10:14:37 -0400
committerAli Jafri <ali.jafri@arm.com>2015-07-03 10:14:37 -0400
commita262908acc0a641700a03fcea89c48133f0467cd (patch)
tree86fa711fe3b1d3459d0f0088a3cfffa5d14a6dad /src/mem/abstract_mem.cc
parentaa5bbe81f6fd18d824608d48a5adf74ea2c5b51d (diff)
downloadgem5-a262908acc0a641700a03fcea89c48133f0467cd.tar.xz
mem: Add clean evicts to improve snoop filter tracking
This patch adds eviction notices to the caches, to provide accurate tracking of cache blocks in snoop filters. We add the CleanEvict message to the memory heirarchy and use both CleanEvicts and Writebacks with BLOCK_CACHED flags to propagate notice of clean and dirty evictions respectively, down the memory hierarchy. Note that the BLOCK_CACHED flag indicates whether there exist any copies of the evicted block in the caches above the evicting cache. The purpose of the CleanEvict message is to notify snoop filters of silent evictions in the relevant caches. The CleanEvict message behaves much like a Writeback. CleanEvict is a write and a request but unlike a Writeback, CleanEvict does not have data and does not need exclusive access to the block. The cache generates the CleanEvict message on a fill resulting in eviction of a clean block. Before travelling downwards CleanEvict requests generate zero-time snoop requests to check if the same block is cached in upper levels of the memory heirarchy. If the block exists, the cache discards the CleanEvict message. The snoops check the tags, writeback queue and the MSHRs of upper level caches in a manner similar to snoops generated from HardPFReqs. Currently CleanEvicts keep travelling towards main memory unless they encounter the block corresponding to their address or reach main memory (since we have no well defined point of serialisation). Main memory simply discards CleanEvict messages. We have modified the behavior of Writebacks, such that they generate snoops to check for the presence of blocks in upper level caches. It is possible in our current implmentation for a lower level cache to be writing back a block while a shared copy of the same block exists in the upper level cache. If the snoops find the same block in upper level caches, we set the BLOCK_CACHED flag in the Writeback message. We have also added logic to account for interaction of other message types with CleanEvicts waiting in the writeback queue. A simple example is of a response arriving at a cache removing any CleanEvicts to the same address from the cache's writeback queue.
Diffstat (limited to 'src/mem/abstract_mem.cc')
-rw-r--r--src/mem/abstract_mem.cc12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/mem/abstract_mem.cc b/src/mem/abstract_mem.cc
index ec1be04e1..4690a5d80 100644
--- a/src/mem/abstract_mem.cc
+++ b/src/mem/abstract_mem.cc
@@ -322,15 +322,21 @@ AbstractMemory::checkLockedAddrList(PacketPtr pkt)
void
AbstractMemory::access(PacketPtr pkt)
{
- assert(AddrRange(pkt->getAddr(),
- pkt->getAddr() + pkt->getSize() - 1).isSubset(range));
-
if (pkt->memInhibitAsserted()) {
DPRINTF(MemoryAccess, "mem inhibited on 0x%x: not responding\n",
pkt->getAddr());
return;
}
+ if (pkt->cmd == MemCmd::CleanEvict) {
+ DPRINTF(MemoryAccess, "CleanEvict on 0x%x: not responding\n",
+ pkt->getAddr());
+ return;
+ }
+
+ assert(AddrRange(pkt->getAddr(),
+ pkt->getAddr() + (pkt->getSize() - 1)).isSubset(range));
+
uint8_t *hostAddr = pmemAddr + pkt->getAddr() - range.start();
if (pkt->cmd == MemCmd::SwapReq) {