From: Ron Dreslinski Date: Tue, 10 Oct 2006 05:32:18 +0000 (-0400) Subject: Fix several bugs pertaining to upgrades/mem leaks. X-Git-Tag: m5_2.0_beta2~104^2~22^2~3^2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cc78d86661dfccaca2f144d5bdcc75761bf52521;p=gem5.git Fix several bugs pertaining to upgrades/mem leaks. src/mem/cache/base_cache.cc: Fix a bug about not having a request to send src/mem/cache/base_cache.hh: Fix a bug with the blocking code src/mem/cache/cache.hh: AFix a bug with snoop hits in WB buffer src/mem/cache/cache_impl.hh: Fix a bug with snoop hits in WB buffer Also, add better DPRINTF's src/mem/cache/miss/miss_queue.cc: Fix a bug with upgrades (Need to clean it up later) src/mem/cache/miss/mshr.cc: Fix a memory leak bug, still some outstanding with writebacks not being deleted src/mem/cache/miss/mshr_queue.cc: Fix a bug about upgrades (need to clean up later) src/mem/packet.hh: Fix for newly added cmd attribute for upgrades tests/configs/memtest.py: More interesting testcase --HG-- extra : convert_revision : fcb4f17dd58b537bb4f67a8c835f50e455e8c688 --- diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 8e2f4d233..c4d42c0a4 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -104,10 +104,12 @@ BaseCache::CachePort::recvRetry() if (result) drainList.pop_front(); } + if (!result) return; } if (!isCpuSide) { + if (!cache->doMasterRequest()) return; pkt = cache->getPacket(); MSHR* mshr = (MSHR*)pkt->senderState; bool success = sendTiming(pkt); @@ -179,10 +181,23 @@ BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort, Packet *_pkt) void BaseCache::CacheEvent::process() { + if (!cachePort->drainList.empty()) { + //We have some responses to drain first + bool result = true; + while (result && !cachePort->drainList.empty()) { + result = cachePort->sendTiming(cachePort->drainList.front()); + if (result) + cachePort->drainList.pop_front(); + } + if (!result) return; + } + if (!pkt) { if (!cachePort->isCpuSide) { + //For now, doMasterRequest somehow is still getting set + if (!cachePort->cache->doMasterRequest()) return; //MSHR pkt = cachePort->cache->getPacket(); MSHR* mshr = (MSHR*) pkt->senderState; diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index c45f3b71b..e0f12940f 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -392,11 +392,13 @@ class BaseCache : public MemObject blocked_causes[cause]++; blockedCycle = curTick; } + int old_state = blocked; if (!(blocked & flag)) { //Wasn't already blocked for this cause blocked |= flag; DPRINTF(Cache,"Blocking for cause %s\n", cause); - cpuSidePort->setBlocked(); + if (!old_state) + cpuSidePort->setBlocked(); } } @@ -408,10 +410,12 @@ class BaseCache : public MemObject void setBlockedForSnoop(BlockedCause cause) { uint8_t flag = 1 << cause; - if (!(blocked & flag)) { + uint8_t old_state = blockedSnoop; + if (!(blockedSnoop & flag)) { //Wasn't already blocked for this cause blockedSnoop |= flag; - memSidePort->setBlocked(); + if (!old_state) + memSidePort->setBlocked(); } } diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index 923bf8255..41b270030 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -103,6 +103,7 @@ class Cache : public BaseCache * Used to append to target list, to cause an invalidation. */ Packet * invalidatePkt; + Request *invalidateReq; /** * Temporarily move a block into a MSHR. diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 5c12075cd..8c0521b52 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -163,10 +163,8 @@ Cache(const std::string &_name, prefetcher->setCache(this); prefetcher->setTags(tags); prefetcher->setBuffer(missQueue); -#if 0 - invalidatePkt = new Packet; - invalidatePkt->cmd = Packet::InvalidateReq; -#endif + invalidateReq = new Request((Addr) NULL, blkSize, 0); + invalidatePkt = new Packet(invalidateReq, Packet::InvalidateReq, 0); } template @@ -267,6 +265,7 @@ template Packet * Cache::getPacket() { + assert(missQueue->havePending()); Packet * pkt = missQueue->getPacket(); if (pkt) { if (!pkt->req->isUncacheable()) { @@ -292,7 +291,17 @@ Cache::sendResult(PacketPtr &pkt, MSHR* mshr, bool //Temp Hack for UPGRADES if (pkt->cmd == Packet::UpgradeReq) { pkt->flags &= ~CACHE_LINE_FILL; - handleResponse(pkt); + BlkType *blk = tags->findBlock(pkt); + CacheBlk::State old_state = (blk) ? blk->status : 0; + CacheBlk::State new_state = coherence->getNewState(pkt,old_state); + DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", + pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state); + //Set the state on the upgrade + memcpy(pkt->getPtr(), blk->data, blkSize); + PacketList writebacks; + tags->handleFill(blk, mshr, new_state, writebacks, pkt); + assert(writebacks.empty()); + missQueue->handleResponse(pkt, curTick + hitLatency); } } else if (pkt && !pkt->req->isUncacheable()) { pkt->flags &= ~NACKED_LINE; @@ -402,7 +411,8 @@ Cache::snoop(Packet * &pkt) assert(!(pkt->flags & SATISFIED)); pkt->flags |= SATISFIED; pkt->flags |= NACKED_LINE; - warn("NACKs from devices not connected to the same bus not implemented\n"); + ///@todo NACK's from other levels + //warn("NACKs from devices not connected to the same bus not implemented\n"); //respondToSnoop(pkt, curTick + hitLatency); return; } @@ -416,7 +426,7 @@ Cache::snoop(Packet * &pkt) //@todo Make it so that a read to a pending read can't be exclusive now. //Set the address so find match works - panic("Don't have invalidates yet\n"); + //panic("Don't have invalidates yet\n"); invalidatePkt->addrOverride(pkt->getAddr()); //Append the invalidate on @@ -447,7 +457,7 @@ Cache::snoop(Packet * &pkt) pkt->flags |= SHARED_LINE; assert(pkt->isRead()); - Addr offset = pkt->getAddr() & ~(blkSize - 1); + Addr offset = pkt->getAddr() & (blkSize - 1); assert(offset < blkSize); assert(pkt->getSize() <= blkSize); assert(offset + pkt->getSize() <=blkSize); @@ -468,16 +478,16 @@ Cache::snoop(Packet * &pkt) CacheBlk::State new_state; bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); if (satisfy) { - DPRINTF(Cache, "Cache snooped a %s request and now supplying data," + DPRINTF(Cache, "Cache snooped a %s request for addr %x and now supplying data," "new state is %i\n", - pkt->cmdString(), new_state); + pkt->cmdString(), blk_addr, new_state); tags->handleSnoop(blk, new_state, pkt); respondToSnoop(pkt, curTick + hitLatency); return; } - if (blk) DPRINTF(Cache, "Cache snooped a %s request, new state is %i\n", - pkt->cmdString(), new_state); + if (blk) DPRINTF(Cache, "Cache snooped a %s request for addr %x, new state is %i\n", + pkt->cmdString(), blk_addr, new_state); tags->handleSnoop(blk, new_state); } @@ -695,15 +705,15 @@ Cache::snoopProbe(PacketPtr &pkt) CacheBlk::State new_state = 0; bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); if (satisfy) { - DPRINTF(Cache, "Cache snooped a %s request and now supplying data," + DPRINTF(Cache, "Cache snooped a %s request for addr %x and now supplying data," "new state is %i\n", - pkt->cmdString(), new_state); + pkt->cmdString(), blk_addr, new_state); tags->handleSnoop(blk, new_state, pkt); return hitLatency; } - if (blk) DPRINTF(Cache, "Cache snooped a %s request, new state is %i\n", - pkt->cmdString(), new_state); + if (blk) DPRINTF(Cache, "Cache snooped a %s request for addr %x, new state is %i\n", + pkt->cmdString(), blk_addr, new_state); tags->handleSnoop(blk, new_state); return 0; } diff --git a/src/mem/cache/miss/miss_queue.cc b/src/mem/cache/miss/miss_queue.cc index bdb7a39c8..c7b0e0890 100644 --- a/src/mem/cache/miss/miss_queue.cc +++ b/src/mem/cache/miss/miss_queue.cc @@ -515,6 +515,14 @@ MissQueue::setBusCmd(Packet * &pkt, Packet::Command cmd) assert(pkt->senderState != 0); MSHR * mshr = (MSHR*)pkt->senderState; mshr->originalCmd = pkt->cmd; + if (cmd == Packet::UpgradeReq || cmd == Packet::InvalidateReq) { + pkt->flags |= NO_ALLOCATE; + pkt->flags &= ~CACHE_LINE_FILL; + } + else if (!pkt->req->isUncacheable() && !pkt->isNoAllocate() && + (cmd & (1 << 6)/*NeedsResponse*/)) { + pkt->flags |= CACHE_LINE_FILL; + } if (pkt->isCacheFill() || pkt->isNoAllocate()) pkt->cmd = cmd; } diff --git a/src/mem/cache/miss/mshr.cc b/src/mem/cache/miss/mshr.cc index f36032672..455798f15 100644 --- a/src/mem/cache/miss/mshr.cc +++ b/src/mem/cache/miss/mshr.cc @@ -100,6 +100,7 @@ MSHR::deallocate() { assert(targets.empty()); assert(ntargets == 0); + delete pkt; pkt = NULL; inService = false; //allocIter = NULL; diff --git a/src/mem/cache/miss/mshr_queue.cc b/src/mem/cache/miss/mshr_queue.cc index bd9667529..78897c8fb 100644 --- a/src/mem/cache/miss/mshr_queue.cc +++ b/src/mem/cache/miss/mshr_queue.cc @@ -213,7 +213,7 @@ void MSHRQueue::markInService(MSHR* mshr) { //assert(mshr == pendingList.front()); - if (!mshr->pkt->needsResponse()) { + if (!(mshr->pkt->needsResponse() || mshr->pkt->cmd == Packet::UpgradeReq)) { assert(mshr->getNumTargets() == 0); deallocate(mshr); return; diff --git a/src/mem/packet.hh b/src/mem/packet.hh index e8cbfd10e..8d9f8ee60 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -59,8 +59,8 @@ typedef std::list PacketList; #define SNOOP_COMMIT 1 << 6 //For statistics we need max number of commands, hard code it at -//20 for now. @todo fix later -#define NUM_MEM_CMDS 1 << 9 +//for now. @todo fix later +#define NUM_MEM_CMDS 1 << 10 /** * A Packet is used to encapsulate a transfer between two objects in diff --git a/tests/configs/memtest.py b/tests/configs/memtest.py index c5cd0246d..17992976c 100644 --- a/tests/configs/memtest.py +++ b/tests/configs/memtest.py @@ -36,7 +36,7 @@ from m5.objects import * class L1(BaseCache): latency = 1 block_size = 64 - mshrs = 4 + mshrs = 12 tgts_per_mshr = 8 protocol = CoherenceProtocol(protocol='moesi') @@ -46,14 +46,14 @@ class L1(BaseCache): class L2(BaseCache): block_size = 64 - latency = 100 + latency = 10 mshrs = 92 tgts_per_mshr = 16 write_buffers = 8 #MAX CORES IS 8 with the fals sharing method nb_cores = 8 -cpus = [ MemTest(max_loads=1e12) for i in xrange(nb_cores) ] +cpus = [ MemTest(max_loads=1e12, percent_uncacheable=0) for i in xrange(nb_cores) ] # system simulated system = System(cpu = cpus, funcmem = PhysicalMemory(), @@ -61,7 +61,7 @@ system = System(cpu = cpus, funcmem = PhysicalMemory(), # l2cache & bus system.toL2Bus = Bus() -system.l2c = L2(size='4MB', assoc=8) +system.l2c = L2(size='64kB', assoc=8) system.l2c.cpu_side = system.toL2Bus.port # connect l2c to membus @@ -90,5 +90,4 @@ system.physmem.port = system.membus.port root = Root( system = system ) root.system.mem_mode = 'timing' -#root.trace.flags="InstExec" -root.trace.flags="Bus" +root.trace.flags="Cache"