Fix handling of writeback-induced writebacks in atomic mode.
authorSteve Reinhardt <stever@gmail.com>
Tue, 25 Mar 2008 14:01:21 +0000 (10:01 -0400)
committerSteve Reinhardt <stever@gmail.com>
Tue, 25 Mar 2008 14:01:21 +0000 (10:01 -0400)
--HG--
extra : convert_revision : 4fa64f8a929f1aa36a9d5a71b8d1816b497aca4c

src/mem/cache/cache.hh
src/mem/cache/cache_impl.hh

index f5f65d4dd5bd2eb0587fd36d444b8246fae1d983..88c9deb7bab4c701f25813bf8b972e580845c6aa 100644 (file)
@@ -162,7 +162,8 @@ class Cache : public BaseCache
      * @return Pointer to the cache block touched by the request. NULL if it
      * was a miss.
      */
-    bool access(PacketPtr pkt, BlkType *&blk, int &lat);
+    bool access(PacketPtr pkt, BlkType *&blk,
+                int &lat, PacketList &writebacks);
 
     /**
      *Handle doing the Compare and Swap function for SPARC.
index 47d20f915ae9e7f05c055036eb7119c72162e4cf..7bab3012b5bdb1a6059bb5e0af4d0f82aa615042 100644 (file)
@@ -260,7 +260,8 @@ Cache<TagStore>::squash(int threadNum)
 
 template<class TagStore>
 bool
-Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat)
+Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk,
+                        int &lat, PacketList &writebacks)
 {
     if (pkt->req->isUncacheable())  {
         blk = NULL;
@@ -308,7 +309,6 @@ Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat)
     // into the cache without having a writeable copy (or any copy at
     // all).
     if (pkt->cmd == MemCmd::Writeback) {
-        PacketList writebacks;
         assert(blkSize == pkt->getSize());
         if (blk == NULL) {
             // need to do a replacement
@@ -323,12 +323,6 @@ Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat)
         }
         std::memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize);
         blk->status |= BlkDirty;
-        // copy writebacks from replacement to write buffer
-        while (!writebacks.empty()) {
-            PacketPtr wbPkt = writebacks.front();
-            allocateWriteBuffer(wbPkt, curTick + hitLatency, true);
-            writebacks.pop_front();
-        }
         // nothing else to do; writeback doesn't expect response
         assert(!pkt->needsResponse());
         hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
@@ -427,13 +421,13 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
 
     int lat = hitLatency;
     BlkType *blk = NULL;
-    bool satisfied = access(pkt, blk, lat);
+    PacketList writebacks;
+
+    bool satisfied = access(pkt, blk, lat, writebacks);
 
 #if 0
     /** @todo make the fast write alloc (wh64) work with coherence. */
 
-    PacketList writebacks;
-
     // If this is a block size write/hint (WH64) allocate the block here
     // if the coherence protocol allows it.
     if (!blk && pkt->getSize() >= blkSize && coherence->allowFastWrites() &&
@@ -451,13 +445,6 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
             ++fastWrites;
         }
     }
-
-    // copy writebacks to write buffer
-    while (!writebacks.empty()) {
-        PacketPtr wbPkt = writebacks.front();
-        allocateWriteBuffer(wbPkt, time, true);
-        writebacks.pop_front();
-    }
 #endif
 
     bool needsResponse = pkt->needsResponse();
@@ -527,6 +514,13 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
         }
     }
 
+    // copy writebacks to write buffer
+    while (!writebacks.empty()) {
+        PacketPtr wbPkt = writebacks.front();
+        allocateWriteBuffer(wbPkt, time, true);
+        writebacks.pop_front();
+    }
+
     return true;
 }
 
@@ -614,8 +608,9 @@ Cache<TagStore>::atomicAccess(PacketPtr pkt)
     // access in timing mode
 
     BlkType *blk = NULL;
+    PacketList writebacks;
 
-    if (!access(pkt, blk, lat)) {
+    if (!access(pkt, blk, lat, writebacks)) {
         // MISS
         PacketPtr busPkt = getBusPacket(pkt, blk, pkt->needsExclusive());
 
@@ -646,21 +641,20 @@ Cache<TagStore>::atomicAccess(PacketPtr pkt)
             pkt->makeAtomicResponse();
             pkt->copyError(busPkt);
         } else if (isCacheFill && !is_error) {
-            PacketList writebacks;
             blk = handleFill(busPkt, blk, writebacks);
             satisfyCpuSideRequest(pkt, blk);
             delete busPkt;
-
-            // Handle writebacks if needed
-            while (!writebacks.empty()){
-                PacketPtr wbPkt = writebacks.front();
-                memSidePort->sendAtomic(wbPkt);
-                writebacks.pop_front();
-                delete wbPkt;
-            }
         }
     }
 
+    // Handle writebacks if needed
+    while (!writebacks.empty()){
+        PacketPtr wbPkt = writebacks.front();
+        memSidePort->sendAtomic(wbPkt);
+        writebacks.pop_front();
+        delete wbPkt;
+    }
+
     // We now have the block one way or another (hit or completed miss)
 
     if (pkt->needsResponse()) {