diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc index 71fbb1884..3e5ed42bc 100644 --- a/src/mem/cache/cache.cc +++ b/src/mem/cache/cache.cc @@ -1190,7 +1190,6 @@ Cache::recvTimingResp(PacketPtr pkt) // Initial target is used just for stats MSHR::Target *initial_tgt = mshr->getTarget(); - CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure()); int stats_cmd_idx = initial_tgt->pkt->cmdToIndex(); Tick miss_latency = curTick() - initial_tgt->recvTime; PacketList writebacks; @@ -1212,16 +1211,20 @@ Cache::recvTimingResp(PacketPtr pkt) miss_latency; } + // upgrade deferred targets if we got exclusive + if (!pkt->sharedAsserted()) { + mshr->promoteExclusive(); + } + bool is_fill = !mshr->isForward && (pkt->isRead() || pkt->cmd == MemCmd::UpgradeResp); + CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure()); + if (is_fill && !is_error) { DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n", pkt->getAddr()); - // give mshr a chance to do some dirty work - mshr->handleFill(pkt, blk); - blk = handleFill(pkt, blk, writebacks); assert(blk != NULL); } @@ -1262,9 +1265,10 @@ Cache::recvTimingResp(PacketPtr pkt) // from above. if (tgt_pkt->cmd == MemCmd::WriteLineReq) { assert(!is_error); - + // we got the block in exclusive state, so promote any + // deferred targets if possible + mshr->promoteExclusive(); // NB: we use the original packet here and not the response! - mshr->handleFill(tgt_pkt, blk); blk = handleFill(tgt_pkt, blk, writebacks); assert(blk != NULL); diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc index 085b8dae0..f71ff6524 100644 --- a/src/mem/cache/mshr.cc +++ b/src/mem/cache/mshr.cc @@ -430,11 +430,10 @@ MSHR::promoteDeferredTargets() void -MSHR::handleFill(PacketPtr pkt, CacheBlk *blk) +MSHR::promoteExclusive() { - if (!pkt->sharedAsserted() - && !(hasPostInvalidate() || hasPostDowngrade()) - && deferredTargets.needsExclusive) { + if (deferredTargets.needsExclusive && + !(hasPostInvalidate() || hasPostDowngrade())) { // We got an exclusive response, but we have deferred targets // which are waiting to request an exclusive copy (not because // of a pending invalidate). This can happen if the original diff --git a/src/mem/cache/mshr.hh b/src/mem/cache/mshr.hh index 65740c107..11ca4db40 100644 --- a/src/mem/cache/mshr.hh +++ b/src/mem/cache/mshr.hh @@ -282,7 +282,7 @@ class MSHR : public Packet::SenderState, public Printable bool promoteDeferredTargets(); - void handleFill(PacketPtr pkt, CacheBlk *blk); + void promoteExclusive(); bool checkFunctional(PacketPtr pkt);