A couple more minor bug fixes for multilevel coherence.
authorSteve Reinhardt <stever@eecs.umich.edu>
Tue, 24 Jul 2007 05:28:40 +0000 (22:28 -0700)
committerSteve Reinhardt <stever@eecs.umich.edu>
Tue, 24 Jul 2007 05:28:40 +0000 (22:28 -0700)
--HG--
extra : convert_revision : 370f9e34911157765be6fd49e826fa1af589b466

src/mem/cache/cache_impl.hh
src/mem/cache/miss/mshr.cc

index efd7f4588ee58114ed2b9831d1a122b386f54193..412d1059983a183128e5edefb23c3d27eb9676c1 100644 (file)
@@ -148,7 +148,13 @@ void
 Cache<TagStore>::satisfyCpuSideRequest(PacketPtr pkt, BlkType *blk)
 {
     assert(blk);
-    assert(pkt->needsExclusive() ? blk->isWritable() : blk->isValid());
+    // Occasionally this is not true... if we are a lower-level cache
+    // satisfying a string of Read and ReadEx requests from
+    // upper-level caches, a Read will mark the block as shared but we
+    // can satisfy a following ReadEx anyway since we can rely on the
+    // Read requester(s) to have buffered the ReadEx snoop and to
+    // invalidate their blocks after receiving them.
+    // assert(pkt->needsExclusive() ? blk->isWritable() : blk->isValid());
     assert(pkt->getOffset(blkSize) + pkt->getSize() <= blkSize);
 
     // Check RMW operations first since both isRead() and
@@ -727,7 +733,7 @@ Cache<TagStore>::handleResponse(PacketPtr pkt)
             Tick completion_time;
             if (blk != NULL) {
                 satisfyCpuSideRequest(target->pkt, blk);
-                // How many bytes pass the first request is this one
+                // How many bytes past the first request is this one
                 int transfer_offset =
                     target->pkt->getOffset(blkSize) - initial_offset;
                 if (transfer_offset < 0) {
@@ -738,10 +744,9 @@ Cache<TagStore>::handleResponse(PacketPtr pkt)
                 completion_time = tags->getHitLatency() +
                     transfer_offset ? pkt->finishTime : pkt->firstWordTime;
 
-                if (!target->pkt->req->isUncacheable()) {
-                    missLatency[target->pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] +=
-                        completion_time - target->recvTime;
-                }
+                assert(!target->pkt->req->isUncacheable());
+                missLatency[target->pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] +=
+                    completion_time - target->recvTime;
             } else {
                 // not a cache fill, just forwarding response
                 completion_time = tags->getHitLatency() + pkt->finishTime;
@@ -1004,7 +1009,9 @@ template<class TagStore>
 void
 Cache<TagStore>::snoopTiming(PacketPtr pkt)
 {
-    if (pkt->req->isUncacheable()) {
+    // Note that some deferred snoops don't have requests, since the
+    // original access may have already completed
+    if (pkt->req && pkt->req->isUncacheable()) {
         //Can't get a hit on an uncacheable address
         //Revisit this for multi level coherence
         return;
index 9b05aea3f2bcd6137b0d14ae3481ea38e077ee11..7f216ad39479343caa28ddf8eb91e454f06f6c43 100644 (file)
@@ -208,7 +208,7 @@ MSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order)
 bool
 MSHR::handleSnoop(PacketPtr pkt, Counter _order)
 {
-    if (!inService || downstreamPending) {
+    if (!inService || (pkt->isExpressSnoop() && downstreamPending)) {
         // Request has not been issued yet, or it's been issued
         // locally but is buffered unissued at some downstream cache
         // which is forwarding us this snoop.  Either way, the packet
@@ -249,13 +249,19 @@ MSHR::handleSnoop(PacketPtr pkt, Counter _order)
     if (targets->needsExclusive || pkt->needsExclusive()) {
         // actual target device (typ. PhysicalMemory) will delete the
         // packet on reception, so we need to save a copy here
-        targets->add(new Packet(pkt), curTick, _order, false);
+        PacketPtr cp_pkt = new Packet(pkt);
+        targets->add(cp_pkt, curTick, _order, false);
         ++ntargets;
 
         if (targets->needsExclusive) {
             // We're awaiting an exclusive copy, so ownership is pending.
             // It's up to us to respond once the data arrives.
             pkt->assertMemInhibit();
+        } else {
+            // Someone else may respond before we get around to
+            // processing this snoop, which means the copied request
+            // pointer will no longer be valid
+            cp_pkt->req = NULL;
         }
 
         if (pkt->needsExclusive()) {