diff options
Diffstat (limited to 'src/mem/cache/mshr.cc')
-rw-r--r-- | src/mem/cache/mshr.cc | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc index 79a91da2b..bc46ed267 100644 --- a/src/mem/cache/mshr.cc +++ b/src/mem/cache/mshr.cc @@ -62,10 +62,11 @@ using namespace std; MSHR::MSHR() : readyTime(0), _isUncacheable(false), downstreamPending(false), - pendingDirty(false), postInvalidate(false), - postDowngrade(false), queue(NULL), order(0), addr(0), size(0), - isSecure(false), inService(false), isForward(false), - threadNum(InvalidThreadID), data(NULL) + pendingDirty(false), pendingClean(false), + postInvalidate(false), postDowngrade(false), + _isObsolete(false), queue(NULL), order(0), addr(0), + size(0), isSecure(false), inService(false), + isForward(false), threadNum(InvalidThreadID), data(NULL) { } @@ -213,7 +214,9 @@ MSHR::allocate(Addr _addr, int _size, PacketPtr target, Tick whenReady, isForward = false; _isUncacheable = target->req->isUncacheable(); inService = false; + pendingClean = (target->cmd == MemCmd::WriteInvalidateReq); downstreamPending = false; + _isObsolete = false; threadNum = 0; assert(targets.isReset()); // Don't know of a case where we would allocate a new MSHR for a @@ -250,7 +253,8 @@ MSHR::markInService(PacketPtr pkt) assert(pkt != NULL); inService = true; - pendingDirty = (targets.needsExclusive || + pendingDirty = ((targets.needsExclusive && + (pkt->cmd != MemCmd::WriteInvalidateReq)) || (!pkt->sharedAsserted() && pkt->memInhibitAsserted())); postInvalidate = postDowngrade = false; @@ -366,7 +370,12 @@ MSHR::handleSnoop(PacketPtr pkt, Counter _order) targets.add(cp_pkt, curTick(), _order, Target::FromSnoop, downstreamPending && targets.needsExclusive); - if (isPendingDirty()) { + // WriteInvalidates must writeback and should not be inhibited on + // account of its snoops discovering MSHRs wanting exclusive access + // to what it wrote. We don't want to push this check higher, + // however, because we want to be sure to add an invalidating + // Target::FromSnoop, above. + if (isPendingDirty() && (pkt->cmd != MemCmd::WriteInvalidateReq)) { pkt->assertMemInhibit(); pkt->setSupplyExclusive(); } @@ -374,6 +383,13 @@ MSHR::handleSnoop(PacketPtr pkt, Counter _order) if (pkt->needsExclusive()) { // This transaction will take away our pending copy postInvalidate = true; + + // Do not defer (i.e. return true) the snoop if the block is + // going to be clean once the MSHR completes, as the data is + // ready now. + if (isPendingClean()) { + return false; + } } } |