diff options
author | Steve Reinhardt <stever@eecs.umich.edu> | 2007-06-26 14:53:15 -0700 |
---|---|---|
committer | Steve Reinhardt <stever@eecs.umich.edu> | 2007-06-26 14:53:15 -0700 |
commit | 7dacbcf49262605a75e461149ec7bd7a00fca7b7 (patch) | |
tree | cd1f5994e726ecd59badb23b8a264c669d37a876 /src/mem | |
parent | f697e959a17646500bca7c12e6bb7b30e047f1bb (diff) | |
download | gem5-7dacbcf49262605a75e461149ec7bd7a00fca7b7.tar.xz |
Handle replacement of block with pending upgrade.
src/mem/cache/tags/lru.cc:
Add some replacement DPRINTFs
--HG--
extra : convert_revision : 7993ec24d6af7e7774d04ce36f20e3f43f887fd9
Diffstat (limited to 'src/mem')
-rw-r--r-- | src/mem/cache/cache_impl.hh | 27 | ||||
-rw-r--r-- | src/mem/cache/miss/mshr.cc | 53 | ||||
-rw-r--r-- | src/mem/cache/miss/mshr.hh | 11 | ||||
-rw-r--r-- | src/mem/cache/tags/lru.cc | 4 |
4 files changed, 89 insertions, 6 deletions
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 48efc5ca3..d01adde78 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -300,7 +300,6 @@ Cache<TagStore,Coherence>::timingAccess(PacketPtr pkt) return true; } - PacketList writebacks; int lat = hitLatency; bool satisfied = false; @@ -319,6 +318,8 @@ Cache<TagStore,Coherence>::timingAccess(PacketPtr pkt) } #if 0 + PacketList writebacks; + // If this is a block size write/hint (WH64) allocate the block here // if the coherence protocol allows it. /** @todo make the fast write alloc (wh64) work with coherence. */ @@ -338,7 +339,6 @@ Cache<TagStore,Coherence>::timingAccess(PacketPtr pkt) ++fastWrites; } } -#endif // copy writebacks to write buffer while (!writebacks.empty()) { @@ -346,6 +346,7 @@ Cache<TagStore,Coherence>::timingAccess(PacketPtr pkt) allocateBuffer(wbPkt, time, true); writebacks.pop_front(); } +#endif bool needsResponse = pkt->needsResponse(); @@ -676,6 +677,15 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr pkt) DPRINTF(Cache, "Block for addr %x being updated in Cache\n", pkt->getAddr()); BlkType *blk = tags->findBlock(pkt->getAddr()); + + if (blk == NULL && pkt->cmd == MemCmd::UpgradeResp) { + if (!mshr->handleReplacedPendingUpgrade(pkt)) { + mq->markPending(mshr); + requestMemSideBus((RequestCause)mq->index, pkt->finishTime); + return; + } + } + PacketList writebacks; blk = handleFill(pkt, blk, writebacks); deallocate = satisfyMSHR(mshr, pkt, blk); @@ -747,15 +757,20 @@ Cache<TagStore,Coherence>::handleFill(PacketPtr pkt, BlkType *blk, Addr addr = pkt->getAddr(); if (blk == NULL) { - // better have read new data + // better have read new data... assert(pkt->isRead()); // need to do a replacement blk = tags->findReplacement(addr, writebacks); if (blk->isValid()) { + 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", - tags->regenerateBlkAddr(blk->tag, blk->set), addr, - blk->isDirty() ? "writeback" : "clean"); + repl_addr, addr, blk->isDirty() ? "writeback" : "clean"); if (blk->isDirty()) { // Save writeback packet for handling by caller @@ -992,7 +1007,7 @@ Cache<TagStore,Coherence>::getNextMSHR() return conflict_mshr; } - // No conclifts; issue read + // No conflicts; issue read return miss_mshr; } diff --git a/src/mem/cache/miss/mshr.cc b/src/mem/cache/miss/mshr.cc index fc8d2175e..ca5e38601 100644 --- a/src/mem/cache/miss/mshr.cc +++ b/src/mem/cache/miss/mshr.cc @@ -75,6 +75,8 @@ MSHR::allocate(Addr _addr, int _size, PacketPtr target, assert(deferredTargets.empty()); deferredNeedsExclusive = false; pendingInvalidate = false; + replacedPendingUpgrade = false; + data = NULL; } void @@ -171,6 +173,57 @@ 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::handleReplacedPendingUpgrade(Packet *pkt) +{ + // @TODO: if upgrade is nacked and replacedPendingUpgradeDirty is true, then we need to writeback the data (or rel + assert(pkt->cmd == MemCmd::UpgradeResp); + 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; + return true; +} + + +void MSHR::dump() { ccprintf(cerr, diff --git a/src/mem/cache/miss/mshr.hh b/src/mem/cache/miss/mshr.hh index 92288cf52..a9380d99a 100644 --- a/src/mem/cache/miss/mshr.hh +++ b/src/mem/cache/miss/mshr.hh @@ -105,12 +105,20 @@ class MSHR : public Packet::SenderState bool deferredNeedsExclusive; bool pendingInvalidate; + /** Is there a pending upgrade that got replaced? */ + bool replacedPendingUpgrade; + bool replacedPendingUpgradeDirty; /** Thread number of the miss. */ short threadNum; /** The number of currently allocated targets. */ short ntargets; + + /** Data buffer (if needed). Currently used only for pending + * upgrade handling. */ + uint8_t *data; + /** * Pointer to this MSHR on the ready list. * @sa MissQueue, MSHRQueue::readyList @@ -204,6 +212,9 @@ public: bool promoteDeferredTargets(); + void handleReplacement(CacheBlk *blk, int blkSize); + bool handleReplacedPendingUpgrade(Packet *pkt); + /** * Prints the contents of this MSHR to stderr. */ diff --git a/src/mem/cache/tags/lru.cc b/src/mem/cache/tags/lru.cc index 334312aaf..fa46aff7b 100644 --- a/src/mem/cache/tags/lru.cc +++ b/src/mem/cache/tags/lru.cc @@ -173,6 +173,8 @@ LRU::findBlock(Addr addr, int &lat) if (blk != NULL) { // move this block to head of the MRU list sets[set].moveToHead(blk); + DPRINTF(Cache, "set %x: moving blk %x to MRU\n", + set, regenerateBlkAddr(tag, set)); if (blk->whenReady > curTick && blk->whenReady - curTick > hitLatency) { lat = blk->whenReady - curTick; @@ -214,6 +216,8 @@ LRU::findReplacement(Addr addr, PacketList &writebacks) } } + DPRINTF(Cache, "set %x: selecting blk %x for replacement\n", + set, regenerateBlkAddr(blk->tag, set)); return blk; } |