71c71,75
< prefetchOnAccess(p->prefetch_on_access)
---
> prefetchOnAccess(p->prefetch_on_access),
> clusivity(p->clusivity),
> tempBlockWriteback(nullptr),
> writebackTempBlockAtomicEvent(this, false,
> EventBase::Delayed_Writeback_Pri)
201,204c205,208
< // on ReadExReq we give up our copy unconditionally
< if (blk != tempBlock)
< tags->invalidate(blk);
< blk->invalidate();
---
> // on ReadExReq we give up our copy unconditionally,
> // even if this cache is mostly inclusive, we may want
> // to revisit this
> invalidateBlock(blk);
223c227,228
< // along with exclusivity, do so
---
> // (inhibit set) along with exclusivity
> // (shared not set), do so
224a230,243
>
> // if this cache is mostly inclusive, we keep
> // the block as writable (exclusive), and pass
> // it upwards as writable and dirty
> // (modified), hence we have multiple caches
> // considering the same block writable,
> // something that we get away with due to the
> // fact that: 1) this cache has been
> // considered the ordering points and
> // responded to all snoops up till now, and 2)
> // we always snoop upwards before consulting
> // the local cache, both on a normal request
> // (snooping done by the crossbar), and on a
> // snoop
225a245,250
>
> // if this cache is mostly exclusive with
> // respect to the cache above, drop the block
> if (clusivity == Enums::mostly_excl) {
> invalidateBlock(blk);
> }
244,246c269,272
< assert(blk != tempBlock);
< tags->invalidate(blk);
< blk->invalidate();
---
>
> // for invalidations we could be looking at the temp block
> // (for upgrades we always allocate)
> invalidateBlock(blk);
764c790,791
< mshr->allocateTarget(pkt, forward_time, order++);
---
> mshr->allocateTarget(pkt, forward_time, order++,
> allocOnFill(pkt->cmd));
1030c1057,1058
< blk = handleFill(pkt, blk, writebacks);
---
> blk = handleFill(pkt, blk, writebacks,
> allocOnFill(pkt->cmd));
1036c1064,1065
< blk = handleFill(bus_pkt, blk, writebacks);
---
> blk = handleFill(bus_pkt, blk, writebacks,
> allocOnFill(pkt->cmd));
1059c1088
< // Handle writebacks (from the response handling) if needed
---
> // do any writebacks resulting from the response handling
1061a1091,1115
> // if we used temp block, check to see if its valid and if so
> // clear it out, but only do so after the call to recvAtomic is
> // finished so that any downstream observers (such as a snoop
> // filter), first see the fill, and only then see the eviction
> if (blk == tempBlock && tempBlock->isValid()) {
> // the atomic CPU calls recvAtomic for fetch and load/store
> // sequentuially, and we may already have a tempBlock
> // writeback from the fetch that we have not yet sent
> if (tempBlockWriteback) {
> // if that is the case, write the prevoius one back, and
> // do not schedule any new event
> writebackTempBlockAtomic();
> } else {
> // the writeback/clean eviction happens after the call to
> // recvAtomic has finished (but before any successive
> // calls), so that the response handling from the fill is
> // allowed to happen first
> schedule(writebackTempBlockAtomicEvent, curTick());
> }
>
> tempBlockWriteback = blk->isDirty() ? writebackBlk(blk) :
> cleanEvictBlk(blk);
> blk->invalidate();
> }
>
1217c1271
< blk = handleFill(pkt, blk, writebacks);
---
> blk = handleFill(pkt, blk, writebacks, mshr->allocOnFill);
1261c1315
< blk = handleFill(tgt_pkt, blk, writebacks);
---
> blk = handleFill(tgt_pkt, blk, writebacks, mshr->allocOnFill);
1365,1367c1419
< assert(blk != tempBlock);
< tags->invalidate(blk);
< blk->invalidate();
---
> invalidateBlock(blk);
1590a1643,1649
> void
> Cache::invalidateBlock(CacheBlk *blk)
> {
> if (blk != tempBlock)
> tags->invalidate(blk);
> blk->invalidate();
> }
1598c1657,1658
< Cache::handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks)
---
> Cache::handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks,
> bool allocate)
1622,1623c1682,1685
< // need to do a replacement
< blk = allocateBlock(addr, is_secure, writebacks);
---
> // need to do a replacement if allocating, otherwise we stick
> // with the temporary storage
> blk = allocate ? allocateBlock(addr, is_secure, writebacks) : NULL;
>
1625,1626c1687,1689
< // No replaceable block... just use temporary storage to
< // complete the current request and then get rid of it
---
> // No replaceable block or a mostly exclusive
> // cache... just use temporary storage to complete the
> // current request and then get rid of it
1879a1943
> assert(!pkt->memInhibitAsserted());
1914,1916c1978
< if (blk != tempBlock)
< tags->invalidate(blk);
< blk->invalidate();
---
> invalidateBlock(blk);