// the delay provided by the crossbar
     Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
 
+    // Note that lat is passed by reference here. The function
+    // access() will set the lat value.
     Cycles lat;
     CacheBlk *blk = nullptr;
-    bool satisfied = false;
-    {
-        PacketList writebacks;
-        // Note that lat is passed by reference here. The function
-        // access() will set the lat value.
-        satisfied = access(pkt, blk, lat, writebacks);
-
-        // After the evicted blocks are selected, they must be forwarded
-        // to the write buffer to ensure they logically precede anything
-        // happening below
-        doWritebacks(writebacks, clockEdge(lat + forwardLatency));
-    }
+    bool satisfied = access(pkt, blk, lat);
 
     // Here we charge the headerDelay that takes into account the latencies
     // of the bus, if the packet comes from it.
             miss_latency;
     }
 
-    PacketList writebacks;
-
     bool is_fill = !mshr->isForward &&
         (pkt->isRead() || pkt->cmd == MemCmd::UpgradeResp ||
          mshr->wasWholeLineWrite);
 
         const bool allocate = (writeAllocator && mshr->wasWholeLineWrite) ?
             writeAllocator->allocate() : mshr->allocOnFill();
-        blk = handleFill(pkt, blk, writebacks, allocate);
+        blk = handleFill(pkt, blk, allocate);
         assert(blk != nullptr);
         ppFill->notify(pkt);
     }
 
     // if we used temp block, check to see if its valid and then clear it out
     if (blk == tempBlock && tempBlock->isValid()) {
-        evictBlock(blk, writebacks);
+        evictBlock(blk, clockEdge(forwardLatency) + pkt->headerDelay);
     }
 
-    const Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
-    // copy writebacks to write buffer
-    doWritebacks(writebacks, forward_time);
-
     DPRINTF(CacheVerbose, "%s: Leaving with %s\n", __func__, pkt->print());
     delete pkt;
 }
     Cycles lat = lookupLatency;
 
     CacheBlk *blk = nullptr;
-    PacketList writebacks;
-    bool satisfied = access(pkt, blk, lat, writebacks);
+    bool satisfied = access(pkt, blk, lat);
 
     if (pkt->isClean() && blk && blk->isDirty()) {
         // A cache clean opearation is looking for a dirty
         DPRINTF(CacheVerbose, "%s: packet %s found block: %s\n",
                 __func__, pkt->print(), blk->print());
         PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest(), pkt->id);
-        writebacks.push_back(wb_pkt);
         pkt->setSatisfied();
+        doWritebacksAtomic(wb_pkt);
     }
 
-    // handle writebacks resulting from the access here to ensure they
-    // logically precede anything happening below
-    doWritebacksAtomic(writebacks);
-    assert(writebacks.empty());
-
     if (!satisfied) {
-        lat += handleAtomicReqMiss(pkt, blk, writebacks);
+        lat += handleAtomicReqMiss(pkt, blk);
     }
 
     // Note that we don't invoke the prefetcher at all in atomic mode.
     // immediately rather than calling requestMemSideBus() as we do
     // there).
 
-    // do any writebacks resulting from the response handling
-    doWritebacksAtomic(writebacks);
-
     // if we used temp block, check to see if its valid and if so
     // clear it out, but only do so after the call to recvAtomic is
     // finished so that any downstream observers (such as a snoop
 
 bool
 BaseCache::updateCompressionData(CacheBlk *blk, const uint64_t* data,
-                                 PacketList &writebacks)
+    uint32_t delay, Cycles tag_latency)
 {
     // tempBlock does not exist in the tags, so don't do anything for it.
     if (blk == tempBlock) {
             if (evict_blk->wasPrefetched()) {
                 unusedPrefetches++;
             }
-            evictBlock(evict_blk, writebacks);
+            Cycles lat = calculateAccessLatency(evict_blk, delay, tag_latency);
+            evictBlock(evict_blk, clockEdge(lat + forwardLatency));
         }
     }
 
 }
 
 bool
-BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
-                  PacketList &writebacks)
+BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat)
 {
     // sanity check
     assert(pkt->isRequest());
 
         if (!blk) {
             // need to do a replacement
-            blk = allocateBlock(pkt, writebacks);
+            blk = allocateBlock(pkt, tag_latency);
             if (!blk) {
                 // no replaceable block available: give up, fwd to next level.
                 incMissCount(pkt);
             // a smaller size, and now it doesn't fit the entry anymore).
             // If that is the case we might need to evict blocks.
             if (!updateCompressionData(blk, pkt->getConstPtr<uint64_t>(),
-                writebacks)) {
+                pkt->headerDelay, tag_latency)) {
                 // This is a failed data expansion (write), which happened
                 // after finding the replacement entries and accessing the
                 // block's data. There were no replaceable entries available
                 return false;
             } else {
                 // a writeback that misses needs to allocate a new block
-                blk = allocateBlock(pkt, writebacks);
+                blk = allocateBlock(pkt, tag_latency);
                 if (!blk) {
                     // no replaceable block available: give up, fwd to
                     // next level.
             // a smaller size, and now it doesn't fit the entry anymore).
             // If that is the case we might need to evict blocks.
             if (!updateCompressionData(blk, pkt->getConstPtr<uint64_t>(),
-                writebacks)) {
+                pkt->headerDelay, tag_latency)) {
                 // This is a failed data expansion (write), which happened
                 // after finding the replacement entries and accessing the
                 // block's data. There were no replaceable entries available
 }
 
 CacheBlk*
-BaseCache::handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks,
-                      bool allocate)
+BaseCache::handleFill(PacketPtr pkt, CacheBlk *blk, bool allocate)
 {
     assert(pkt->isResponse());
     Addr addr = pkt->getAddr();
         // better have read new data...
         assert(pkt->hasData() || pkt->cmd == MemCmd::InvalidateResp);
 
-        // need to do a replacement if allocating, otherwise we stick
-        // with the temporary storage
-        blk = allocate ? allocateBlock(pkt, writebacks) : nullptr;
+        // Need to do a replacement if allocating, otherwise we stick
+        // with the temporary storage. The tag lookup has already been
+        // done to decide the eviction victims, so it is set to 0 here.
+        // The eviction itself, however, is delayed until the new data
+        // for the block that is requesting the replacement arrives.
+        blk = allocate ? allocateBlock(pkt, Cycles(0)) : nullptr;
 
         if (!blk) {
             // No replaceable block or a mostly exclusive
 }
 
 CacheBlk*
-BaseCache::allocateBlock(const PacketPtr pkt, PacketList &writebacks)
+BaseCache::allocateBlock(const PacketPtr pkt, Cycles tag_latency)
 {
     // Get address
     const Addr addr = pkt->getAddr();
                     unusedPrefetches++;
                 }
 
-                evictBlock(blk, writebacks);
+                Cycles lat =
+                    calculateAccessLatency(blk, pkt->headerDelay, tag_latency);
+                evictBlock(blk, clockEdge(lat + forwardLatency));
             }
         }
 
 }
 
 void
-BaseCache::evictBlock(CacheBlk *blk, PacketList &writebacks)
+BaseCache::evictBlock(CacheBlk *blk, Tick forward_timing)
 {
     PacketPtr pkt = evictBlock(blk);
     if (pkt) {
-        writebacks.push_back(pkt);
+        if (system->isTimingMode()) {
+            doWritebacks(pkt, forward_timing);
+        } else {
+            doWritebacksAtomic(pkt);
+        }
     }
 }
 
                     __func__, pkt->print(), blk->print());
             PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest(),
                                              pkt->id);
-            PacketList writebacks;
-            writebacks.push_back(wb_pkt);
-            doWritebacks(writebacks, 0);
+            doWritebacks(wb_pkt, 0);
         }
 
         return false;
 
      * @param pkt The memory request to perform.
      * @param blk The cache block to be updated.
      * @param lat The latency of the access.
-     * @param writebacks List for any writebacks that need to be performed.
      * @return Boolean indicating whether the request was satisfied.
      */
-    virtual bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
-                        PacketList &writebacks);
+    virtual bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat);
 
     /*
      * Handle a timing request that hit in the cache
      *
      * @param pkt The packet with the requests
      * @param blk The referenced block
-     * @param writebacks A list with packets for any performed writebacks
      * @return Cycles for handling the request
      */
-    virtual Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk,
-                                       PacketList &writebacks) = 0;
+    virtual Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk) = 0;
 
     /**
      * Performs the access specified by the request.
 
     /**
      * Insert writebacks into the write buffer
+     *
+     * @param pkt The writeback packet.
+     * @param forward_time Tick to which the writeback should be scheduled.
      */
-    virtual void doWritebacks(PacketList& writebacks, Tick forward_time) = 0;
+    virtual void doWritebacks(PacketPtr pkt, Tick forward_time) = 0;
 
     /**
-     * Send writebacks down the memory hierarchy in atomic mode
+     * Send writebacks down the memory hierarchy in atomic mode.
+     *
+     * @param pkt The writeback packet.
      */
-    virtual void doWritebacksAtomic(PacketList& writebacks) = 0;
+    virtual void doWritebacksAtomic(PacketPtr pkt) = 0;
 
     /**
      * Create an appropriate downstream bus request packet.
      */
     void writebackTempBlockAtomic() {
         assert(tempBlockWriteback != nullptr);
-        PacketList writebacks{tempBlockWriteback};
-        doWritebacksAtomic(writebacks);
+        doWritebacksAtomic(tempBlockWriteback);
         tempBlockWriteback = nullptr;
     }
 
      *
      * @param blk The block to be overwriten.
      * @param data A pointer to the data to be compressed (blk's new data).
-     * @param writebacks List for any writebacks that need to be performed.
+     * @param delay The delay until the packet's metadata is present.
+     * @param tag_latency Latency to access the tags of the replacement victim.
      * @return Whether operation is successful or not.
      */
     bool updateCompressionData(CacheBlk *blk, const uint64_t* data,
-                               PacketList &writebacks);
+        uint32_t delay, Cycles tag_latency);
 
     /**
      * Perform any necessary updates to the block and perform any data
      * Populates a cache block and handles all outstanding requests for the
      * satisfied fill request. This version takes two memory requests. One
      * contains the fill data, the other is an optional target to satisfy.
-     * Note that the reason we return a list of writebacks rather than
-     * inserting them directly in the write buffer is that this function
-     * is called by both atomic and timing-mode accesses, and in atomic
-     * mode we don't mess with the write buffer (we just perform the
-     * writebacks atomically once the original request is complete).
      *
      * @param pkt The memory request with the fill data.
      * @param blk The cache block if it already exists.
-     * @param writebacks List for any writebacks that need to be performed.
      * @param allocate Whether to allocate a block or use the temp block
      * @return Pointer to the new cache block.
      */
-    CacheBlk *handleFill(PacketPtr pkt, CacheBlk *blk,
-                         PacketList &writebacks, bool allocate);
+    CacheBlk *handleFill(PacketPtr pkt, CacheBlk *blk, bool allocate);
 
     /**
-     * Allocate a new block and perform any necessary writebacks
-     *
-     * Find a victim block and if necessary prepare writebacks for any
-     * existing data. May return nullptr if there are no replaceable
-     * blocks. If a replaceable block is found, it inserts the new block in
-     * its place. The new block, however, is not set as valid yet.
+     * Allocate a new block for the packet's data. The victim block might be
+     * valid, and thus the necessary writebacks are done. May return nullptr
+     * if there are no replaceable blocks. If a replaceable block is found,
+     * it inserts the new block in its place. The new block, however, is not
+     * set as valid yet.
      *
      * @param pkt Packet holding the address to update
-     * @param writebacks A list of writeback packets for the evicted blocks
+     * @param tag_latency Latency to access the tags of the replacement victim.
      * @return the allocated block
      */
-    CacheBlk *allocateBlock(const PacketPtr pkt, PacketList &writebacks);
+    CacheBlk *allocateBlock(const PacketPtr pkt, Cycles tag_latency);
+
     /**
      * Evict a cache block.
      *
      * Performs a writeback if necesssary and invalidates the block
      *
      * @param blk Block to invalidate
-     * @param writebacks Return a list of packets with writebacks
+     * @param forward_time Tick to which the writeback should be scheduled if
+     *                     in timing mode.
      */
-    void evictBlock(CacheBlk *blk, PacketList &writebacks);
+    void evictBlock(CacheBlk *blk, Tick forward_time);
 
     /**
      * Invalidate a cache block.
 
 /////////////////////////////////////////////////////
 
 bool
-Cache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
-              PacketList &writebacks)
+Cache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat)
 {
 
     if (pkt->req->isUncacheable()) {
 
         DPRINTF(Cache, "%s for %s\n", __func__, pkt->print());
 
+        // lookupLatency is the latency in case the request is uncacheable.
+        lat = lookupLatency;
+
         // flush and invalidate any existing block
         CacheBlk *old_blk(tags->findBlock(pkt->getAddr(), pkt->isSecure()));
         if (old_blk && old_blk->isValid()) {
-            BaseCache::evictBlock(old_blk, writebacks);
+            BaseCache::evictBlock(old_blk, clockEdge(lat + forwardLatency));
         }
 
         blk = nullptr;
-        // lookupLatency is the latency in case the request is uncacheable.
-        lat = lookupLatency;
         return false;
     }
 
-    return BaseCache::access(pkt, blk, lat, writebacks);
+    return BaseCache::access(pkt, blk, lat);
 }
 
 void
-Cache::doWritebacks(PacketList& writebacks, Tick forward_time)
+Cache::doWritebacks(PacketPtr pkt, Tick forward_time)
 {
-    while (!writebacks.empty()) {
-        PacketPtr wbPkt = writebacks.front();
-        // We use forwardLatency here because we are copying writebacks to
-        // write buffer.
-
-        // Call isCachedAbove for Writebacks, CleanEvicts and
-        // WriteCleans to discover if the block is cached above.
-        if (isCachedAbove(wbPkt)) {
-            if (wbPkt->cmd == MemCmd::CleanEvict) {
-                // Delete CleanEvict because cached copies exist above. The
-                // packet destructor will delete the request object because
-                // this is a non-snoop request packet which does not require a
-                // response.
-                delete wbPkt;
-            } else if (wbPkt->cmd == MemCmd::WritebackClean) {
-                // clean writeback, do not send since the block is
-                // still cached above
-                assert(writebackClean);
-                delete wbPkt;
-            } else {
-                assert(wbPkt->cmd == MemCmd::WritebackDirty ||
-                       wbPkt->cmd == MemCmd::WriteClean);
-                // Set BLOCK_CACHED flag in Writeback and send below, so that
-                // the Writeback does not reset the bit corresponding to this
-                // address in the snoop filter below.
-                wbPkt->setBlockCached();
-                allocateWriteBuffer(wbPkt, forward_time);
-            }
+    // We use forwardLatency here because we are copying writebacks to
+    // write buffer.
+
+    // Call isCachedAbove for Writebacks, CleanEvicts and
+    // WriteCleans to discover if the block is cached above.
+    if (isCachedAbove(pkt)) {
+        if (pkt->cmd == MemCmd::CleanEvict) {
+            // Delete CleanEvict because cached copies exist above. The
+            // packet destructor will delete the request object because
+            // this is a non-snoop request packet which does not require a
+            // response.
+            delete pkt;
+        } else if (pkt->cmd == MemCmd::WritebackClean) {
+            // clean writeback, do not send since the block is
+            // still cached above
+            assert(writebackClean);
+            delete pkt;
         } else {
-            // If the block is not cached above, send packet below. Both
-            // CleanEvict and Writeback with BLOCK_CACHED flag cleared will
-            // reset the bit corresponding to this address in the snoop filter
-            // below.
-            allocateWriteBuffer(wbPkt, forward_time);
+            assert(pkt->cmd == MemCmd::WritebackDirty ||
+                   pkt->cmd == MemCmd::WriteClean);
+            // Set BLOCK_CACHED flag in Writeback and send below, so that
+            // the Writeback does not reset the bit corresponding to this
+            // address in the snoop filter below.
+            pkt->setBlockCached();
+            allocateWriteBuffer(pkt, forward_time);
         }
-        writebacks.pop_front();
+    } else {
+        // If the block is not cached above, send packet below. Both
+        // CleanEvict and Writeback with BLOCK_CACHED flag cleared will
+        // reset the bit corresponding to this address in the snoop filter
+        // below.
+        allocateWriteBuffer(pkt, forward_time);
     }
 }
 
 void
-Cache::doWritebacksAtomic(PacketList& writebacks)
+Cache::doWritebacksAtomic(PacketPtr pkt)
 {
-    while (!writebacks.empty()) {
-        PacketPtr wbPkt = writebacks.front();
-        // Call isCachedAbove for both Writebacks and CleanEvicts. If
-        // isCachedAbove returns true we set BLOCK_CACHED flag in Writebacks
-        // and discard CleanEvicts.
-        if (isCachedAbove(wbPkt, false)) {
-            if (wbPkt->cmd == MemCmd::WritebackDirty ||
-                wbPkt->cmd == MemCmd::WriteClean) {
-                // Set BLOCK_CACHED flag in Writeback and send below,
-                // so that the Writeback does not reset the bit
-                // corresponding to this address in the snoop filter
-                // below. We can discard CleanEvicts because cached
-                // copies exist above. Atomic mode isCachedAbove
-                // modifies packet to set BLOCK_CACHED flag
-                memSidePort.sendAtomic(wbPkt);
-            }
-        } else {
-            // If the block is not cached above, send packet below. Both
-            // CleanEvict and Writeback with BLOCK_CACHED flag cleared will
-            // reset the bit corresponding to this address in the snoop filter
-            // below.
-            memSidePort.sendAtomic(wbPkt);
+    // Call isCachedAbove for both Writebacks and CleanEvicts. If
+    // isCachedAbove returns true we set BLOCK_CACHED flag in Writebacks
+    // and discard CleanEvicts.
+    if (isCachedAbove(pkt, false)) {
+        if (pkt->cmd == MemCmd::WritebackDirty ||
+            pkt->cmd == MemCmd::WriteClean) {
+            // Set BLOCK_CACHED flag in Writeback and send below,
+            // so that the Writeback does not reset the bit
+            // corresponding to this address in the snoop filter
+            // below. We can discard CleanEvicts because cached
+            // copies exist above. Atomic mode isCachedAbove
+            // modifies packet to set BLOCK_CACHED flag
+            memSidePort.sendAtomic(pkt);
         }
-        writebacks.pop_front();
-        // In case of CleanEvicts, the packet destructor will delete the
-        // request object because this is a non-snoop request packet which
-        // does not require a response.
-        delete wbPkt;
+    } else {
+        // If the block is not cached above, send packet below. Both
+        // CleanEvict and Writeback with BLOCK_CACHED flag cleared will
+        // reset the bit corresponding to this address in the snoop filter
+        // below.
+        memSidePort.sendAtomic(pkt);
     }
-}
 
+    // In case of CleanEvicts, the packet destructor will delete the
+    // request object because this is a non-snoop request packet which
+    // does not require a response.
+    delete pkt;
+}
 
 void
 Cache::recvTimingSnoopResp(PacketPtr pkt)
 
 
 Cycles
-Cache::handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk,
-                           PacketList &writebacks)
+Cache::handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk)
 {
     // deal with the packets that go through the write path of
     // the cache, i.e. any evictions and writes
                 // the write to a whole line
                 const bool allocate = allocOnFill(pkt->cmd) &&
                     (!writeAllocator || writeAllocator->allocate());
-                blk = handleFill(bus_pkt, blk, writebacks, allocate);
+                blk = handleFill(bus_pkt, blk, allocate);
                 assert(blk != NULL);
                 is_invalidate = false;
                 satisfyRequest(pkt, blk);
                        bus_pkt->cmd == MemCmd::UpgradeResp) {
                 // we're updating cache state to allow us to
                 // satisfy the upstream request from the cache
-                blk = handleFill(bus_pkt, blk, writebacks,
-                                 allocOnFill(pkt->cmd));
+                blk = handleFill(bus_pkt, blk, allocOnFill(pkt->cmd));
                 satisfyRequest(pkt, blk);
                 maintainClusivity(pkt->fromCache(), blk);
             } else {
             DPRINTF(CacheVerbose, "%s: packet (snoop) %s found block: %s\n",
                     __func__, pkt->print(), blk->print());
             PacketPtr wb_pkt = writecleanBlk(blk, pkt->req->getDest(), pkt->id);
-            PacketList writebacks;
-            writebacks.push_back(wb_pkt);
 
             if (is_timing) {
                 // anything that is merely forwarded pays for the forward
                 // latency and the delay provided by the crossbar
                 Tick forward_time = clockEdge(forwardLatency) +
                     pkt->headerDelay;
-                doWritebacks(writebacks, forward_time);
+                doWritebacks(wb_pkt, forward_time);
             } else {
-                doWritebacksAtomic(writebacks);
+                doWritebacksAtomic(wb_pkt);
             }
             pkt->setSatisfied();
         }
 
      */
     void promoteWholeLineWrites(PacketPtr pkt);
 
-    bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
-                PacketList &writebacks) override;
+    bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat) override;
 
     void handleTimingReqHit(PacketPtr pkt, CacheBlk *blk,
                             Tick request_time) override;
 
     void recvTimingReq(PacketPtr pkt) override;
 
-    void doWritebacks(PacketList& writebacks, Tick forward_time) override;
+    void doWritebacks(PacketPtr pkt, Tick forward_time) override;
 
-    void doWritebacksAtomic(PacketList& writebacks) override;
+    void doWritebacksAtomic(PacketPtr pkt) override;
 
     void serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt,
                             CacheBlk *blk) override;
 
     void recvTimingSnoopResp(PacketPtr pkt) override;
 
-    Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk,
-                               PacketList &writebacks) override;
+    Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk) override;
 
     Tick recvAtomic(PacketPtr pkt) override;
 
 
 }
 
 bool
-NoncoherentCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
-                         PacketList &writebacks)
+NoncoherentCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat)
 {
-    bool success = BaseCache::access(pkt, blk, lat, writebacks);
+    bool success = BaseCache::access(pkt, blk, lat);
 
     if (pkt->isWriteback() || pkt->cmd == MemCmd::WriteClean) {
         assert(blk && blk->isValid());
 }
 
 void
-NoncoherentCache::doWritebacks(PacketList& writebacks, Tick forward_time)
+NoncoherentCache::doWritebacks(PacketPtr pkt, Tick forward_time)
 {
-    while (!writebacks.empty()) {
-        PacketPtr wb_pkt = writebacks.front();
-        allocateWriteBuffer(wb_pkt, forward_time);
-        writebacks.pop_front();
-    }
+    allocateWriteBuffer(pkt, forward_time);
 }
 
 void
-NoncoherentCache::doWritebacksAtomic(PacketList& writebacks)
+NoncoherentCache::doWritebacksAtomic(PacketPtr pkt)
 {
-    while (!writebacks.empty()) {
-        PacketPtr wb_pkt = writebacks.front();
-        memSidePort.sendAtomic(wb_pkt);
-        writebacks.pop_front();
-        delete wb_pkt;
-    }
+    memSidePort.sendAtomic(pkt);
+    delete pkt;
 }
 
 void
 
 
 Cycles
-NoncoherentCache::handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk,
-                                      PacketList &writebacks)
+NoncoherentCache::handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk)
 {
     PacketPtr bus_pkt = createMissPacket(pkt, blk, true,
                                          pkt->isWholeLineWrite(blkSize));
         // afterall it is a read response
         DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n",
                 bus_pkt->getAddr());
-        blk = handleFill(bus_pkt, blk, writebacks, allocOnFill(bus_pkt->cmd));
+        blk = handleFill(bus_pkt, blk, allocOnFill(bus_pkt->cmd));
         assert(blk);
     }
     satisfyRequest(pkt, blk);
 
 class NoncoherentCache : public BaseCache
 {
   protected:
-    bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
-                PacketList &writebacks) override;
+    bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat) override;
 
     void handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk,
                              Tick forward_time,
 
     void recvTimingReq(PacketPtr pkt) override;
 
-    void doWritebacks(PacketList& writebacks,
+    void doWritebacks(PacketPtr pkt,
                       Tick forward_time) override;
 
-    void doWritebacksAtomic(PacketList& writebacks) override;
+    void doWritebacksAtomic(PacketPtr pkt) override;
 
     void serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt,
                             CacheBlk *blk) override;
         panic("Unexpected timing snoop response %s", pkt->print());
     }
 
-    Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk,
-                               PacketList &writebacks) override;
+    Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk) override;
 
     Tick recvAtomic(PacketPtr pkt) override;