diff options
author | Nikos Nikoleris <nikos.nikoleris@arm.com> | 2016-09-26 16:43:59 +0100 |
---|---|---|
committer | Nikos Nikoleris <nikos.nikoleris@arm.com> | 2017-12-05 11:47:01 +0000 |
commit | eb2722609a11c992b55bf20dec1823b4118382c6 (patch) | |
tree | 7d2470e13a8a805db4efff8c7b4ff5855f7104a2 | |
parent | 4d8fb74beffc71e2f77bbc725b5f4e7e601333a9 (diff) | |
download | gem5-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-x | src/mem/snoop_filter.cc | 18 |
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); } |