Addr line_addr = cpkt->getAddr() & ~(linesize - 1);
SnoopMask req_port = portToMask(slave_port);
- SnoopItem& sf_item = cachedLocations[line_addr];
+ auto sf_it = cachedLocations.find(line_addr);
+ bool is_hit = (sf_it != cachedLocations.end());
+ // Create a new element through operator[] and modify in-place
+ SnoopItem& sf_item = is_hit ? sf_it->second : cachedLocations[line_addr];
+ SnoopMask interested = sf_item.holder | sf_item.requested;
+
+ totRequests++;
+ if (is_hit) {
+ // Single bit set -> value is a power of two
+ if (isPow2(interested))
+ hitSingleRequests++;
+ else
+ hitMultiRequests++;
+ }
DPRINTF(SnoopFilter, "%s: SF value %x.%x\n",
__func__, sf_item.requested, sf_item.holder);
- if (cpkt->needsResponse()) {
+ if (!cpkt->req->isUncacheable() && cpkt->needsResponse()) {
if (!cpkt->memInhibitAsserted()) {
// Max one request per address per port
panic_if(sf_item.requested & req_port, "double request :( "\
DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n",
__func__, sf_item.requested, sf_item.holder);
}
- SnoopMask interested = (sf_item.holder | sf_item.requested) & ~req_port;
- return snoopSelected(maskToPortList(interested), lookupLatency);
+ return snoopSelected(maskToPortList(interested & ~req_port), lookupLatency);
}
void
DPRINTF(SnoopFilter, "%s: packet src %s addr 0x%x cmd %s\n",
__func__, slave_port.name(), cpkt->getAddr(), cpkt->cmdString());
+ if (cpkt->req->isUncacheable())
+ return;
+
Addr line_addr = cpkt->getAddr() & ~(linesize - 1);
SnoopMask req_port = portToMask(slave_port);
SnoopItem& sf_item = cachedLocations[line_addr];
// Writebacks -> the sender does not have the line anymore
sf_item.holder &= ~req_port;
} else {
- assert(0 == "Handle non-writeback, here");
+ // @todo Add CleanEvicts
+ assert(cpkt->cmd == MemCmd::CleanEvict);
}
DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n",
__func__, sf_item.requested, sf_item.holder);
return snoopAll(lookupLatency);
Addr line_addr = cpkt->getAddr() & ~(linesize - 1);
- SnoopItem& sf_item = cachedLocations[line_addr];
+ auto sf_it = cachedLocations.find(line_addr);
+ bool is_hit = (sf_it != cachedLocations.end());
+ // Create a new element through operator[] and modify in-place
+ SnoopItem& sf_item = is_hit ? sf_it->second : cachedLocations[line_addr];
DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n",
__func__, sf_item.requested, sf_item.holder);
SnoopMask interested = (sf_item.holder | sf_item.requested);
- assert(cpkt->isInvalidate() == cpkt->needsExclusive());
+
+ totSnoops++;
+ if (is_hit) {
+ // Single bit set -> value is a power of two
+ if (isPow2(interested))
+ hitSingleSnoops++;
+ else
+ hitMultiSnoops++;
+ }
+ // ReadEx and Writes require both invalidation and exlusivity, while reads
+ // require neither. Writebacks on the other hand require exclusivity but
+ // not the invalidation. Previously Writebacks did not generate upward
+ // snoops so this was never an aissue. Now that Writebacks generate snoops
+ // we need to special case for Writebacks.
+ assert(cpkt->cmd == MemCmd::Writeback ||
+ (cpkt->isInvalidate() == cpkt->needsExclusive()));
if (cpkt->isInvalidate() && !sf_item.requested) {
// Early clear of the holder, if no other request is currently going on
// @todo: This should possibly be updated even though we do not filter
__func__, rsp_port.name(), req_port.name(), cpkt->getAddr(),
cpkt->cmdString());
+ assert(cpkt->isResponse());
+ assert(cpkt->memInhibitAsserted());
+
+ if (cpkt->req->isUncacheable())
+ return;
+
Addr line_addr = cpkt->getAddr() & ~(linesize - 1);
SnoopMask rsp_mask = portToMask(rsp_port);
SnoopMask req_mask = portToMask(req_port);
SnoopItem& sf_item = cachedLocations[line_addr];
- assert(cpkt->isResponse());
- assert(cpkt->memInhibitAsserted());
-
DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n",
__func__, sf_item.requested, sf_item.holder);
DPRINTF(SnoopFilter, "%s: packet src %s addr 0x%x cmd %s\n",
__func__, slave_port.name(), cpkt->getAddr(), cpkt->cmdString());
+ assert(cpkt->isResponse());
+
+ if (cpkt->req->isUncacheable())
+ return;
+
Addr line_addr = cpkt->getAddr() & ~(linesize - 1);
SnoopMask slave_mask = portToMask(slave_port);
SnoopItem& sf_item = cachedLocations[line_addr];
- assert(cpkt->isResponse());
-
DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n",
__func__, sf_item.requested, sf_item.holder);
__func__, sf_item.requested, sf_item.holder);
}
+void
+SnoopFilter::regStats()
+{
+ totRequests
+ .name(name() + ".tot_requests")
+ .desc("Total number of requests made to the snoop filter.");
+
+ hitSingleRequests
+ .name(name() + ".hit_single_requests")
+ .desc("Number of requests hitting in the snoop filter with a single "\
+ "holder of the requested data.");
+
+ hitMultiRequests
+ .name(name() + ".hit_multi_requests")
+ .desc("Number of requests hitting in the snoop filter with multiple "\
+ "(>1) holders of the requested data.");
+
+ totSnoops
+ .name(name() + ".tot_snoops")
+ .desc("Total number of snoops made to the snoop filter.");
+
+ hitSingleSnoops
+ .name(name() + ".hit_single_snoops")
+ .desc("Number of snoops hitting in the snoop filter with a single "\
+ "holder of the requested data.");
+
+ hitMultiSnoops
+ .name(name() + ".hit_multi_snoops")
+ .desc("Number of snoops hitting in the snoop filter with multiple "\
+ "(>1) holders of the requested data.");
+}
+
SnoopFilter *
SnoopFilterParams::create()
{