Add downward express snoops for invalidations.
authorSteve Reinhardt <stever@eecs.umich.edu>
Fri, 27 Jul 2007 00:04:17 +0000 (17:04 -0700)
committerSteve Reinhardt <stever@eecs.umich.edu>
Fri, 27 Jul 2007 00:04:17 +0000 (17:04 -0700)
--HG--
extra : convert_revision : 4916fa9721d727d8416ad8c07df3a8171d02b2b4

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

index 6db40b6095c3949a7c930f18dac714470469b0ba..2ead54ba682acae3760805bbca4dd1846849f3e1 100644 (file)
@@ -371,6 +371,17 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
         DPRINTF(Cache, "mem inhibited on 0x%x: not responding\n",
                 pkt->getAddr());
         assert(!pkt->req->isUncacheable());
+        // Special tweak for multilevel coherence: snoop downward here
+        // on invalidates since there may be other caches below here
+        // that have shared copies.  Not necessary if we know that
+        // supplier had exclusive copy to begin with.
+        if (pkt->needsExclusive() && !pkt->isSupplyExclusive()) {
+            Packet *snoopPkt = new Packet(pkt, true);  // clear flags
+            snoopPkt->setExpressSnoop();
+            snoopPkt->assertMemInhibit();
+            memSidePort->sendTiming(snoopPkt);
+            // main memory will delete snoopPkt
+        }
         return true;
     }
 
@@ -966,6 +977,7 @@ Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk,
     // we respond in atomic mode), so just figure out what to do now
     // and then do it later
     bool supply = blk->isDirty() && pkt->isRead() && !upperSupply;
+    bool have_exclusive = blk->isWritable();
     bool invalidate = pkt->isInvalidate();
 
     if (pkt->isRead() && !pkt->isInvalidate()) {
@@ -985,6 +997,9 @@ Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk,
     if (supply) {
         assert(!pkt->memInhibitAsserted());
         pkt->assertMemInhibit();
+        if (have_exclusive) {
+            pkt->setSupplyExclusive();
+        }
         if (is_timing) {
             doTimingSupplyResponse(pkt, blk->data, is_deferred);
         } else {
index 7f216ad39479343caa28ddf8eb91e454f06f6c43..5ba3d1ec5a5f21ae0d0734ba85e25cef4ee22dd8 100644 (file)
@@ -257,6 +257,7 @@ MSHR::handleSnoop(PacketPtr pkt, Counter _order)
             // We're awaiting an exclusive copy, so ownership is pending.
             // It's up to us to respond once the data arrives.
             pkt->assertMemInhibit();
+            pkt->setSupplyExclusive();
         } else {
             // Someone else may respond before we get around to
             // processing this snoop, which means the copied request
index 036bd3fd71ff031bfdfd0e4be2bb484bf241c167..c6534d6c9a054a82ff409a743b4986b05c2484bc 100644 (file)
@@ -256,7 +256,11 @@ class Packet : public FastAlloc
         MemInhibit,
         Shared,
         // Special control flags
+        /// Special timing-mode atomic snoop for multi-level coherence.
         ExpressSnoop,
+        /// Does supplier have exclusive copy?
+        /// Useful for multi-level coherence.
+        SupplyExclusive,
         NUM_PACKET_FLAGS
     };
 
@@ -315,13 +319,15 @@ class Packet : public FastAlloc
 
     // Snoop flags
     void assertMemInhibit()     { flags[MemInhibit] = true; }
-    void assertShared()         { flags[Shared] = true; }
     bool memInhibitAsserted()   { return flags[MemInhibit]; }
+    void assertShared()         { flags[Shared] = true; }
     bool sharedAsserted()       { return flags[Shared]; }
 
     // Special control flags
     void setExpressSnoop()      { flags[ExpressSnoop] = true; }
     bool isExpressSnoop()       { return flags[ExpressSnoop]; }
+    void setSupplyExclusive()   { flags[SupplyExclusive] = true; }
+    bool isSupplyExclusive()    { return flags[SupplyExclusive]; }
 
     // Network error conditions... encapsulate them as methods since
     // their encoding keeps changing (from result field to command