Revamp replacement-of-upgrade handling.
authorSteve Reinhardt <stever@eecs.umich.edu>
Wed, 27 Jun 2007 06:30:30 +0000 (23:30 -0700)
committerSteve Reinhardt <stever@eecs.umich.edu>
Wed, 27 Jun 2007 06:30:30 +0000 (23:30 -0700)
--HG--
extra : convert_revision : 9bc09d8ae6d50e6dfbb4ab21514612f9aa102a2e

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

index 161fb801d2ff6c086157510de4883cf9666c3b92..9e8c350666081c411739b5ae085b0bc9da855672 100644 (file)
@@ -136,6 +136,9 @@ class Cache : public BaseCache
     /** Prefetcher */
     BasePrefetcher *prefetcher;
 
+    /** Temporary cache block for occasional transitory use */
+    BlkType *tempBlock;
+
     /**
      * Can this cache should allocate a block on a line-sized write miss.
      */
index 599eecc8211fb18a534f2ee7afb8fa95560c7cbb..3685bc8cbc01ee8e0c935353d44469765ec8c78d 100644 (file)
@@ -58,6 +58,9 @@ Cache<TagStore,Coherence>::Cache(const std::string &_name,
       doFastWrites(params.doFastWrites),
       prefetchMiss(params.prefetchMiss)
 {
+    tempBlock = new BlkType();
+    tempBlock->data = new uint8_t[blkSize];
+
     cpuSidePort = new CpuSidePort(_name + "-cpu_side_port", this);
     memSidePort = new MemSidePort(_name + "-mem_side_port", this);
     cpuSidePort->setOtherPort(memSidePort);
@@ -678,11 +681,8 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr pkt)
                 pkt->getAddr());
         BlkType *blk = tags->findBlock(pkt->getAddr());
 
-        if (!mshr->handleFill(pkt, blk)) {
-            mq->markPending(mshr);
-            requestMemSideBus((RequestCause)mq->index, pkt->finishTime);
-            return;
-        }
+        // give mshr a chance to do some dirty work
+        mshr->handleFill(pkt, blk);
 
         PacketList writebacks;
         blk = handleFill(pkt, blk, writebacks);
@@ -693,6 +693,13 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr pkt)
             allocateBuffer(wbPkt, time, true);
             writebacks.pop_front();
         }
+        // if we used temp block, clear it out
+        if (blk == tempBlock) {
+            if (blk->isDirty()) {
+                allocateBuffer(writebackBlk(blk), time, true);
+            }
+            tags->invalidateBlk(blk);
+        }
     } else {
         if (pkt->req->isUncacheable()) {
             mshr_uncacheable_lat[pkt->cmd.toInt()][0/*pkt->req->getThreadNum()*/] +=
@@ -764,15 +771,26 @@ Cache<TagStore,Coherence>::handleFill(PacketPtr pkt, BlkType *blk,
             Addr repl_addr = tags->regenerateBlkAddr(blk->tag, blk->set);
             MSHR *repl_mshr = mshrQueue.findMatch(repl_addr);
             if (repl_mshr) {
-                repl_mshr->handleReplacement(blk, blkSize);
-            }
-
-            DPRINTF(Cache, "replacement: replacing %x with %x: %s\n",
-                    repl_addr, addr, blk->isDirty() ? "writeback" : "clean");
+                // must be an outstanding upgrade request on block
+                // we're about to replace...
+                assert(!blk->isWritable());
+                assert(repl_mshr->needsExclusive);
+                // too hard to replace block with transient state;
+                // just use temporary storage to complete the current
+                // request and then get rid of it
+                assert(!tempBlock->isValid());
+                blk = tempBlock;
+                tempBlock->set = tags->extractSet(addr);
+                DPRINTF(Cache, "using temp block for %x\n", addr);
+            } else {
+                DPRINTF(Cache, "replacement: replacing %x with %x: %s\n",
+                        repl_addr, addr,
+                        blk->isDirty() ? "writeback" : "clean");
 
-            if (blk->isDirty()) {
-                // Save writeback packet for handling by caller
-                writebacks.push_back(writebackBlk(blk));
+                if (blk->isDirty()) {
+                    // Save writeback packet for handling by caller
+                    writebacks.push_back(writebackBlk(blk));
+                }
             }
         }
 
index 23645cb273da6ebf166099a822ce9b2941cd207c..63b3cacc2c4c2b099ba7ca6643e9021dd311be82 100644 (file)
@@ -76,7 +76,6 @@ MSHR::allocate(Addr _addr, int _size, PacketPtr target,
     deferredNeedsExclusive = false;
     pendingInvalidate = false;
     pendingShared = false;
-    replacedPendingUpgrade = false;
     data = NULL;
 }
 
@@ -185,61 +184,13 @@ MSHR::promoteDeferredTargets()
 
 
 void
-MSHR::handleReplacement(CacheBlk *blk, int blkSize)
-{
-    // must be an outstanding upgrade request on block we're about to
-    // replace...
-    assert(!blk->isWritable());
-    assert(needsExclusive);
-    replacedPendingUpgrade = true;
-
-    // if it's dirty, just remember what happened and allow the
-    // writeback to continue.  we'll reissue a ReadEx later whether
-    // the upgrade succeeds or not
-    if (blk->isDirty()) {
-        replacedPendingUpgradeDirty = true;
-        return;
-    }
-
-    // if not dirty, we need to save it off as it will be only valid
-    // copy in system if upgrade is successful (and may need to be
-    // written back then, as the current owner if any will be
-    // invalidating its block)
-    replacedPendingUpgradeDirty = false;
-    data = new uint8_t[blkSize];
-    std::memcpy(data, blk->data, blkSize);
-}
-
-
-bool
 MSHR::handleFill(Packet *pkt, CacheBlk *blk)
 {
-    if (replacedPendingUpgrade) {
-        // block was replaced while upgrade request was in service
-        assert(pkt->cmd == MemCmd::UpgradeResp);
-        assert(blk == NULL);
-        assert(replacedPendingUpgrade);
-        replacedPendingUpgrade = false; // reset
-        if (replacedPendingUpgradeDirty) {
-            // we wrote back the previous copy; just reissue as a ReadEx
-            return false;
-        }
-
-        // previous copy was not dirty, but we are now owner...  fake out
-        // cache by taking saved data and converting UpgradeResp to
-        // ReadExResp
-        assert(data);
-        pkt->cmd = MemCmd::ReadExResp;
-        pkt->setData(data);
-        delete [] data;
-        data = NULL;
-    } else if (pendingShared) {
+    if (pendingShared) {
         // we snooped another read while this read was in
         // service... assert shared line on its behalf
         pkt->assertShared();
     }
-
-    return true;
 }
 
 
index 07fe5c96c8e61f1017c574a3f589ee830bf85c45..4db7b1cfe0fa40a7e01fafb077fcde59388fcfe4 100644 (file)
@@ -106,9 +106,6 @@ class MSHR : public Packet::SenderState
     bool deferredNeedsExclusive;
     bool pendingInvalidate;
     bool pendingShared;
-    /** Is there a pending upgrade that got replaced? */
-    bool replacedPendingUpgrade;
-    bool replacedPendingUpgradeDirty;
 
     /** Thread number of the miss. */
     short threadNum;
@@ -213,8 +210,7 @@ public:
 
     bool promoteDeferredTargets();
 
-    void handleReplacement(CacheBlk *blk, int blkSize);
-    bool handleFill(Packet *pkt, CacheBlk *blk);
+    void handleFill(Packet *pkt, CacheBlk *blk);
 
     /**
      * Prints the contents of this MSHR to stderr.