summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Nikoleris <nikos.nikoleris@arm.com>2016-09-26 16:43:59 +0100
committerNikos Nikoleris <nikos.nikoleris@arm.com>2017-12-05 11:47:01 +0000
commiteb2722609a11c992b55bf20dec1823b4118382c6 (patch)
tree7d2470e13a8a805db4efff8c7b4ff5855f7104a2
parent4d8fb74beffc71e2f77bbc725b5f4e7e601333a9 (diff)
downloadgem5-eb2722609a11c992b55bf20dec1823b4118382c6.tar.xz
mem: Handle CMO responses in the snoop filter
Previously responses would either transfer the ownership of the line or the actual data to the cache that send out the original request. Cache clean operations are different since they bring neither data nor ownership. When they are also invalidating the cache that send out the original request will invalidate any existing copies. This patch makes the snoop filter handle the cache clean responses accordingly. Change-Id: I27165cb45b9dc57882526329c62db35f100d23df Reviewed-by: Stephan Diestelhorst <stephan.diestelhorst@arm.com> Reviewed-by: Sudhanshu Jha <sudhanshu.jha@arm.com> Reviewed-by: Anouk Van Laer <anouk.vanlaer@arm.com> Reviewed-on: https://gem5-review.googlesource.com/5053 Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
-rwxr-xr-xsrc/mem/snoop_filter.cc18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/mem/snoop_filter.cc b/src/mem/snoop_filter.cc
index 252fbb524..3e1dae6c7 100755
--- a/src/mem/snoop_filter.cc
+++ b/src/mem/snoop_filter.cc
@@ -362,10 +362,22 @@ SnoopFilter::updateResponse(const Packet* cpkt, const SlavePort& slave_port)
panic_if(!(sf_item.requested & slave_mask), "SF value %x.%x missing "\
"request bit\n", sf_item.requested, sf_item.holder);
- // Update the residency of the cache line.
- sf_item.holder |= slave_mask;
sf_item.requested &= ~slave_mask;
- assert(sf_item.holder | sf_item.requested);
+ // Update the residency of the cache line.
+
+ if (cpkt->req->isCacheMaintenance()) {
+ // A cache clean response does not carry any data so it
+ // shouldn't change the holders, unless it is invalidating.
+ if (cpkt->isInvalidate()) {
+ sf_item.holder &= ~slave_mask;
+ }
+ eraseIfNullEntry(sf_it);
+ } else {
+ // Any other response implies that a cache above will have the
+ // block.
+ sf_item.holder |= slave_mask;
+ assert(sf_item.holder | sf_item.requested);
+ }
DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n",
__func__, sf_item.requested, sf_item.holder);
}