50a51,61
> void
> SnoopFilter::eraseIfNullEntry(SnoopFilterCache::iterator& sf_it)
> {
> SnoopItem& sf_item = sf_it->second;
> if (!(sf_item.requested | sf_item.holder)) {
> cachedLocations.erase(sf_it);
> DPRINTF(SnoopFilter, "%s: Removed SF entry.\n",
> __func__);
> }
> }
>
74a86,90
> // Store unmodified value of snoop filter item in temp storage in
> // case we need to revert because of a send retry in
> // updateRequest.
> retryItem = sf_item;
>
87c103,108
< if (allocate && cpkt->needsResponse()) {
---
> // If we are not allocating, we are done
> if (!allocate)
> return snoopSelected(maskToPortList(interested & ~req_port),
> lookupLatency);
>
> if (cpkt->needsResponse()) {
90c111
< panic_if(sf_item.requested & req_port, "double request :( "\
---
> panic_if(sf_item.requested & req_port, "double request :( " \
94a116,117
> DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n",
> __func__, sf_item.requested, sf_item.holder);
101c124,125
< DPRINTF(SnoopFilter, "%s: not marking request. SF value %x.%x\n",
---
> DPRINTF(SnoopFilter,
> "%s: not marking request. SF value %x.%x\n",
104,105c128,140
< DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n",
< __func__, sf_item.requested, sf_item.holder);
---
> } else { // if (!cpkt->needsResponse())
> assert(cpkt->evictingBlock());
> // make sure that the sender actually had the line
> panic_if(!(sf_item.holder & req_port), "requester %x is not a " \
> "holder :( SF value %x.%x\n", req_port,
> sf_item.requested, sf_item.holder);
> // CleanEvicts and Writebacks -> the sender and all caches above
> // it may not have the line anymore.
> if (!cpkt->isBlockCached()) {
> sf_item.holder &= ~req_port;
> DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n",
> __func__, sf_item.requested, sf_item.holder);
> }
106a142
>
124,129c160,161
< SnoopMask req_port = portToMask(slave_port);
< SnoopItem& sf_item = cachedLocations[line_addr];
<
< DPRINTF(SnoopFilter, "%s: old SF value %x.%x retry: %i\n",
< __func__, sf_item.requested, sf_item.holder, will_retry);
<
---
> auto sf_it = cachedLocations.find(line_addr);
> assert(sf_it != cachedLocations.end());
131,134c163,166
< // Unmark a request that will come again.
< sf_item.requested &= ~req_port;
< return;
< }
---
> // Undo any changes made in lookupRequest to the snoop filter
> // entry if the request will come again. retryItem holds
> // the previous value of the snoopfilter entry.
> sf_it->second = retryItem;
136,154c168,169
< // will_retry == false
< if (!cpkt->needsResponse()) {
< // Packets that will not evoke a response but still need updates of the
< // snoop filter; WRITEBACKs for now only
< if (cpkt->cmd == MemCmd::Writeback) {
< // make sure that the sender actually had the line
< panic_if(sf_item.requested & req_port, "double request :( "\
< "SF value %x.%x\n", sf_item.requested, sf_item.holder);
< panic_if(!(sf_item.holder & req_port), "requester %x is not a "\
< "holder :( SF value %x.%x\n", req_port,
< sf_item.requested, sf_item.holder);
< // Writebacks -> the sender does not have the line anymore
< sf_item.holder &= ~req_port;
< } else {
< // @todo Add CleanEvicts
< assert(cpkt->cmd == MemCmd::CleanEvict);
< }
< DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n",
< __func__, sf_item.requested, sf_item.holder);
---
> DPRINTF(SnoopFilter, "%s: restored SF value %x.%x\n",
> __func__, retryItem.requested, retryItem.holder);
155a171,172
>
> eraseIfNullEntry(sf_it);
175,176d191
< // Create a new element through operator[] and modify in-place
< SnoopItem& sf_item = is_hit ? sf_it->second : cachedLocations[line_addr];
177a193,203
> // If the snoop filter has no entry and its an uncacheable
> // request, do not create a new snoop filter entry, simply return
> // a NULL portlist.
> if (!is_hit && cpkt->req->isUncacheable())
> return snoopDown(lookupLatency);
>
> // If no hit in snoop filter create a new element and update iterator
> if (!is_hit)
> sf_it = cachedLocations.emplace(line_addr, SnoopItem()).first;
> SnoopItem& sf_item = sf_it->second;
>
196c222
< assert(cpkt->cmd == MemCmd::Writeback ||
---
> assert(cpkt->cmd == MemCmd::Writeback || cpkt->req->isUncacheable() ||
204a231
> eraseIfNullEntry(sf_it);
260a288
> assert(sf_item.requested | sf_item.holder);
274c302,305
< SnoopItem& sf_item = cachedLocations[line_addr];
---
> auto sf_it = cachedLocations.find(line_addr);
> if (sf_it == cachedLocations.end())
> sf_it = cachedLocations.emplace(line_addr, SnoopItem()).first;
> SnoopItem& sf_item = sf_it->second;
292a324
> eraseIfNullEntry(sf_it);
320,321c352,354
< // Update the residency of the cache line.
< if (cpkt->needsExclusive() || !cpkt->sharedAsserted())
---
> // Update the residency of the cache line. Here we assume that the
> // line has been zapped in all caches that are not the responder.
> if (cpkt->needsExclusive() || !cpkt->sharedAsserted())
324a358
> assert(sf_item.holder | sf_item.requested);