From: Steve Reinhardt Date: Tue, 25 Mar 2008 14:01:21 +0000 (-0400) Subject: Fix handling of writeback-induced writebacks in atomic mode. X-Git-Tag: copyright_update~11 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=29be31ce3139c36f596e6edafbd3d253ee2200b3;p=gem5.git Fix handling of writeback-induced writebacks in atomic mode. --HG-- extra : convert_revision : 4fa64f8a929f1aa36a9d5a71b8d1816b497aca4c --- diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index f5f65d4dd..88c9deb7b 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -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. diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 47d20f915..7bab3012b 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -260,7 +260,8 @@ Cache::squash(int threadNum) template bool -Cache::access(PacketPtr pkt, BlkType *&blk, int &lat) +Cache::access(PacketPtr pkt, BlkType *&blk, + int &lat, PacketList &writebacks) { if (pkt->req->isUncacheable()) { blk = NULL; @@ -308,7 +309,6 @@ Cache::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::access(PacketPtr pkt, BlkType *&blk, int &lat) } std::memcpy(blk->data, pkt->getPtr(), 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::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::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::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::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::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()) {