summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2016-08-12 14:11:45 +0100
committerAndreas Hansson <andreas.hansson@arm.com>2016-08-12 14:11:45 +0100
commita23e914519de16061340db62d7a5dfc2cc7d027e (patch)
tree6e8edfa3f1893a64331823947a1ade57bc5eb102 /src
parent721efa4d094197404a0df0d2bae6c27b4402c0ef (diff)
downloadgem5-a23e914519de16061340db62d7a5dfc2cc7d027e.tar.xz
mem: Use FromCache attribute in snoop filter allocation
This patch improves the snoop filter allocation decisions by not only looking at whether a port is snooping or not, but also if the packet actually came from a cache. The issue with only looking at isSnooping is that the CPU ports, for example, are snooping, but not actually caching. Previously we ended up incorrectly allocating entries in systems without caches (such as the atomic and timing quick regressions). Eventually these misguided allocations caused the snoop filter to panic due to an excessive size. On the request path we now include the fromCache check on the packet itself, and for responses we check if we actually have a snoop-filter entry. Change-Id: Idd2dbc4f00c7e07d331e9a02658aee30d0350d7e Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-by: Stephan Diestelhorst <stephan.diestelhorst@arm.com> Reviewed-by: Tony Gutierrez <anthony.gutierrez@amd.com>
Diffstat (limited to 'src')
-rwxr-xr-xsrc/mem/snoop_filter.cc32
1 files changed, 19 insertions, 13 deletions
diff --git a/src/mem/snoop_filter.cc b/src/mem/snoop_filter.cc
index 636861c2b..14cdc7e07 100755
--- a/src/mem/snoop_filter.cc
+++ b/src/mem/snoop_filter.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015 ARM Limited
+ * Copyright (c) 2013-2016 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -65,9 +65,9 @@ SnoopFilter::lookupRequest(const Packet* cpkt, const SlavePort& slave_port)
DPRINTF(SnoopFilter, "%s: packet src %s addr 0x%x cmd %s\n",
__func__, slave_port.name(), cpkt->getAddr(), cpkt->cmdString());
- // Ultimately we should check if the packet came from an
- // allocating source, not just if the port is snooping
- bool allocate = !cpkt->req->isUncacheable() && slave_port.isSnooping();
+ // check if the packet came from a cache
+ bool allocate = !cpkt->req->isUncacheable() && slave_port.isSnooping() &&
+ cpkt->fromCache();
Addr line_addr = cpkt->getBlockAddr(linesize);
SnoopMask req_port = portToMask(slave_port);
reqLookupResult = cachedLocations.find(line_addr);
@@ -235,11 +235,12 @@ SnoopFilter::updateSnoopResponse(const Packet* cpkt,
assert(cpkt->isResponse());
assert(cpkt->cacheResponding());
- // Ultimately we should check if the packet came from an
- // allocating source, not just if the port is snooping
- bool allocate = !cpkt->req->isUncacheable() && req_port.isSnooping();
- if (!allocate)
+ // if this snoop response is due to an uncacheable request, or is
+ // being turned into a normal response, there is nothing more to
+ // do
+ if (cpkt->req->isUncacheable() || !req_port.isSnooping()) {
return;
+ }
Addr line_addr = cpkt->getBlockAddr(linesize);
SnoopMask rsp_mask = portToMask(rsp_port);
@@ -268,6 +269,7 @@ SnoopFilter::updateSnoopResponse(const Packet* cpkt,
sf_item.holder = 0;
}
assert(!cpkt->isWriteback());
+ // @todo Deal with invalidating responses
sf_item.holder |= req_mask;
sf_item.requested &= ~req_mask;
assert(sf_item.requested | sf_item.holder);
@@ -319,15 +321,19 @@ SnoopFilter::updateResponse(const Packet* cpkt, const SlavePort& slave_port)
assert(cpkt->isResponse());
- // Ultimately we should check if the packet came from an
- // allocating source, not just if the port is snooping
- bool allocate = !cpkt->req->isUncacheable() && slave_port.isSnooping();
- if (!allocate)
+ // we only allocate if the packet actually came from a cache, but
+ // start by checking if the port is snooping
+ if (cpkt->req->isUncacheable() || !slave_port.isSnooping())
return;
+ // next check if we actually allocated an entry
Addr line_addr = cpkt->getBlockAddr(linesize);
+ auto sf_it = cachedLocations.find(line_addr);
+ if (sf_it == cachedLocations.end())
+ return;
+
SnoopMask slave_mask = portToMask(slave_port);
- SnoopItem& sf_item = cachedLocations[line_addr];
+ SnoopItem& sf_item = sf_it->second;
DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n",
__func__, sf_item.requested, sf_item.holder);