summaryrefslogtreecommitdiff
path: root/src/mem/coherent_xbar.cc
diff options
context:
space:
mode:
authorAli Jafri <ali.jafri@arm.com>2015-09-25 07:26:57 -0400
committerAli Jafri <ali.jafri@arm.com>2015-09-25 07:26:57 -0400
commitceec2bb02c87829f29aa1ebb4573051162264ae8 (patch)
tree32977c2548bb77f64368a7d92218be4e662183f1 /src/mem/coherent_xbar.cc
parent6ac356f93b897c8a80378f114865240cba96b693 (diff)
downloadgem5-ceec2bb02c87829f29aa1ebb4573051162264ae8.tar.xz
mem: Add snoops for CleanEvicts and Writebacks in atomic mode
This patch mirrors the logic in timing mode which sends up snoops to check for cached copies before sending CleanEvicts and Writebacks down the memory hierarchy. In case there is a copy in a cache above, discard CleanEvicts and set the BLOCK_CACHED flag in Writebacks so that writebacks do not reset the cache residency bit in the snoop filter below.
Diffstat (limited to 'src/mem/coherent_xbar.cc')
-rw-r--r--src/mem/coherent_xbar.cc20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/mem/coherent_xbar.cc b/src/mem/coherent_xbar.cc
index b07356ede..7181cb965 100644
--- a/src/mem/coherent_xbar.cc
+++ b/src/mem/coherent_xbar.cc
@@ -605,6 +605,13 @@ CoherentXBar::recvAtomic(PacketPtr pkt, PortID slave_port_id)
" SF size: %i lat: %i\n", __func__,
slavePorts[slave_port_id]->name(), pkt->cmdString(),
pkt->getAddr(), sf_res.first.size(), sf_res.second);
+
+ // let the snoop filter know about the success of the send
+ // operation, and do it even before sending it onwards to
+ // avoid situations where atomic upward snoops sneak in
+ // between and change the filter state
+ snoopFilter->updateRequest(pkt, *slavePorts[slave_port_id], false);
+
snoop_result = forwardAtomic(pkt, slave_port_id, InvalidPortID,
sf_res.first);
} else {
@@ -614,6 +621,15 @@ CoherentXBar::recvAtomic(PacketPtr pkt, PortID slave_port_id)
snoop_response_latency += snoop_result.second;
}
+ // forwardAtomic snooped into peer caches of the sender, and if
+ // this is a clean evict, but the packet is found in a cache, do
+ // not forward it
+ if (pkt->cmd == MemCmd::CleanEvict && pkt->isBlockCached()) {
+ DPRINTF(CoherentXBar, "recvAtomic: Clean evict 0x%x still cached, "
+ "not forwarding\n", pkt->getAddr());
+ return 0;
+ }
+
// even if we had a snoop response, we must continue and also
// perform the actual request at the destination
PortID master_port_id = findPort(pkt->getAddr());
@@ -626,8 +642,8 @@ CoherentXBar::recvAtomic(PacketPtr pkt, PortID slave_port_id)
// forward the request to the appropriate destination
Tick response_latency = masterPorts[master_port_id]->sendAtomic(pkt);
- // Lower levels have replied, tell the snoop filter
- if (snoopFilter && !system->bypassCaches() && pkt->isResponse()) {
+ // if lower levels have replied, tell the snoop filter
+ if (!system->bypassCaches() && snoopFilter && pkt->isResponse()) {
snoopFilter->updateResponse(pkt, *slavePorts[slave_port_id]);
}