summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/cache/cache.cc16
-rw-r--r--src/mem/cache/mshr.cc7
-rw-r--r--src/mem/cache/mshr.hh2
3 files changed, 14 insertions, 11 deletions
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);