From f876bc2bf0e04b888c2748c0cabf8d11b31f41b7 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Fri, 10 Nov 2006 22:45:50 -0500 Subject: More fixes for functional accesses. It now makes the writeback memory leak to crash all configs. Working on that now. src/mem/cache/base_cache.cc: Keep a list of the responders so we can search them on functional accesses. src/mem/cache/base_cache.hh: Properly put things on a list for responses so we can search the list. Also, be sure to check the outgoing ports lists on a functional access (factor some common code out there) src/mem/cache/cache_impl.hh: Properly return when the first read hit on a functional access. Make sure to call to check the other ports list of packets before forwarding it out. --HG-- extra : convert_revision : 1d21cb55ff29c15716617efc48441329707c088a --- src/mem/cache/cache_impl.hh | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 9bb72e85c..176d9159a 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -536,7 +536,7 @@ Cache::probe(PacketPtr &pkt, bool update, if (!update && (pkt->isWrite() || (otherSidePort == cpuSidePort))) { // Still need to change data in all locations. - otherSidePort->sendFunctional(pkt); + otherSidePort->checkAndSendFunctional(pkt); if (pkt->isRead() && pkt->result == Packet::Success) return 0; } @@ -560,30 +560,33 @@ Cache::probe(PacketPtr &pkt, bool update, missQueue->findWrites(blk_addr, writes); if (!update) { + bool notDone = !(pkt->flags & SATISFIED); //Hit in cache (was a block) // Check for data in MSHR and writebuffer. if (mshr) { MSHR::TargetList *targets = mshr->getTargetList(); MSHR::TargetList::iterator i = targets->begin(); MSHR::TargetList::iterator end = targets->end(); - for (; i != end; ++i) { + for (; i != end && notDone; ++i) { PacketPtr target = *i; // If the target contains data, and it overlaps the // probed request, need to update data if (target->intersect(pkt)) { - fixPacket(pkt, target); + DPRINTF(Cache, "Functional %s access to blk_addr %x intersects a MSHR\n", + blk_addr); + notDone = fixPacket(pkt, target); } } } - for (int i = 0; i < writes.size(); ++i) { + for (int i = 0; i < writes.size() && notDone; ++i) { PacketPtr write = writes[i]->pkt; if (write->intersect(pkt)) { - fixPacket(pkt, write); + DPRINTF(Cache, "Functional %s access to blk_addr %x intersects a writeback\n", + pkt->cmdString(), blk_addr); + notDone = fixPacket(pkt, write); } } - if (pkt->isRead() - && pkt->result != Packet::Success - && otherSidePort == memSidePort) { - otherSidePort->sendFunctional(pkt); + if (notDone && otherSidePort == memSidePort) { + otherSidePort->checkAndSendFunctional(pkt); assert(pkt->result == Packet::Success); } return 0; -- cgit v1.2.3 From b22d390721275fec8c07bd57d9ed021e78f3f3f7 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Sun, 12 Nov 2006 06:36:33 -0500 Subject: Yet another small bug in mem system related to flow control src/mem/cache/cache_impl.hh: When upgrades change to readEx make sure to allocate the block Fix dprintf --HG-- extra : convert_revision : 8700a7e47ad042c8708302620b907849c4bfdded --- src/mem/cache/cache_impl.hh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 176d9159a..51aa4f8e7 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -333,6 +333,8 @@ Cache::handleResponse(PacketPtr &pkt) DPRINTF(Cache, "Handling reponse to %x\n", pkt->getAddr()); if (pkt->isCacheFill() && !pkt->isNoAllocate()) { + DPRINTF(Cache, "Block for addr %x being updated in Cache\n", + pkt->getAddr()); blk = tags->findBlock(pkt); CacheBlk::State old_state = (blk) ? blk->status : 0; PacketList writebacks; @@ -483,9 +485,15 @@ Cache::snoop(PacketPtr &pkt) respondToSnoop(pkt, curTick + hitLatency); return; } - if (blk) + if (blk) { DPRINTF(Cache, "Cache snooped a %s request for addr %x, " "new state is %i\n", pkt->cmdString(), blk_addr, new_state); + if (mshr && !mshr->inService && new_state == 0) { + //There was a outstanding write to a shared block, not need ReadEx + //not update, so change No Allocate param in MSHR + mshr->pkt->flags &= ~NO_ALLOCATE; + } + } tags->handleSnoop(blk, new_state); } @@ -534,7 +542,7 @@ Cache::probe(PacketPtr &pkt, bool update, } } - if (!update && (pkt->isWrite() || (otherSidePort == cpuSidePort))) { + if (!update && (otherSidePort == cpuSidePort)) { // Still need to change data in all locations. otherSidePort->checkAndSendFunctional(pkt); if (pkt->isRead() && pkt->result == Packet::Success) @@ -572,7 +580,7 @@ Cache::probe(PacketPtr &pkt, bool update, // probed request, need to update data if (target->intersect(pkt)) { DPRINTF(Cache, "Functional %s access to blk_addr %x intersects a MSHR\n", - blk_addr); + pkt->cmdString(), blk_addr); notDone = fixPacket(pkt, target); } } -- cgit v1.2.3 From 11accacf7c9de8147e68845051a489c251c4e7b1 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Sun, 12 Nov 2006 06:44:05 -0500 Subject: Move code before a early return to make sure it is executed on all paths --HG-- extra : convert_revision : cfdd5b6911422fbb733677c43d027aa4407fbc85 --- src/mem/cache/cache_impl.hh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 51aa4f8e7..8acc67b69 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -476,6 +476,13 @@ Cache::snoop(PacketPtr &pkt) } CacheBlk::State new_state; bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); + + if (blk && mshr && !mshr->inService && new_state == 0) { + //There was a outstanding write to a shared block, not need ReadEx + //not update, so change No Allocate param in MSHR + mshr->pkt->flags &= ~NO_ALLOCATE; + } + if (satisfy) { DPRINTF(Cache, "Cache snooped a %s request for addr %x and " "now supplying data, new state is %i\n", @@ -485,15 +492,10 @@ Cache::snoop(PacketPtr &pkt) respondToSnoop(pkt, curTick + hitLatency); return; } - if (blk) { + if (blk) DPRINTF(Cache, "Cache snooped a %s request for addr %x, " "new state is %i\n", pkt->cmdString(), blk_addr, new_state); - if (mshr && !mshr->inService && new_state == 0) { - //There was a outstanding write to a shared block, not need ReadEx - //not update, so change No Allocate param in MSHR - mshr->pkt->flags &= ~NO_ALLOCATE; - } - } + tags->handleSnoop(blk, new_state); } -- cgit v1.2.3 From a200bccc2065d776d0face971610588f438998e7 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Sun, 12 Nov 2006 09:06:15 -0500 Subject: Handle packets being deleted by lower level properly. Fixes for Mem Leak associated with Writebacks. src/mem/cache/miss/mshr_queue.cc: Fixes for Mem Leak associated with Writebacks. (Double Delete removed) --HG-- extra : convert_revision : 7a52ddd57da35995896f2c4438a58aa53f762416 --- src/mem/cache/cache_impl.hh | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 8acc67b69..df59b0a4f 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -53,6 +53,8 @@ #include "sim/sim_exit.hh" // for SimExitEvent +bool SIGNAL_NACK_HACK; + template bool Cache:: @@ -242,6 +244,11 @@ Cache::access(PacketPtr &pkt) missQueue->handleMiss(pkt, size, curTick + hitLatency); } + if (pkt->cmd == Packet::Writeback) { + //Need to clean up the packet on a writeback miss, but leave the request + delete pkt; + } + return true; } @@ -265,6 +272,7 @@ Cache::getPacket() assert(!doMasterRequest() || missQueue->havePending()); assert(!pkt || pkt->time <= curTick); + SIGNAL_NACK_HACK = false; return pkt; } @@ -273,16 +281,15 @@ void Cache::sendResult(PacketPtr &pkt, MSHR* mshr, bool success) { - if (success && !(pkt && (pkt->flags & NACKED_LINE))) { - if (!mshr->pkt->needsResponse() - && !(mshr->pkt->cmd == Packet::UpgradeReq) - && (pkt && (pkt->flags & SATISFIED))) { - //Writeback, clean up the non copy version of the packet - delete pkt; - } + if (success && !(SIGNAL_NACK_HACK)) { + //Remember if it was an upgrade because writeback MSHR's are removed + //in Mark in Service + bool upgrade = (mshr->pkt && mshr->pkt->cmd == Packet::UpgradeReq); + missQueue->markInService(mshr->pkt, mshr); + //Temp Hack for UPGRADES - if (mshr->pkt && mshr->pkt->cmd == Packet::UpgradeReq) { + if (upgrade) { assert(pkt); //Upgrades need to be fixed pkt->flags &= ~CACHE_LINE_FILL; BlkType *blk = tags->findBlock(pkt); @@ -300,6 +307,7 @@ Cache::sendResult(PacketPtr &pkt, MSHR* mshr, } } else if (pkt && !pkt->req->isUncacheable()) { pkt->flags &= ~NACKED_LINE; + SIGNAL_NACK_HACK = false; pkt->flags &= ~SATISFIED; pkt->flags &= ~SNOOP_COMMIT; @@ -404,6 +412,7 @@ Cache::snoop(PacketPtr &pkt) assert(!(pkt->flags & SATISFIED)); pkt->flags |= SATISFIED; pkt->flags |= NACKED_LINE; + SIGNAL_NACK_HACK = true; ///@todo NACK's from other levels //warn("NACKs from devices not connected to the same bus " //"not implemented\n"); -- cgit v1.2.3