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
This commit is contained in:
Ron Dreslinski 2006-10-10 01:32:18 -04:00
parent ec8a437b2c
commit cc78d86661
9 changed files with 66 additions and 28 deletions

View file

@ -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;

View file

@ -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();
}
}

View file

@ -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.

View file

@ -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<class TagStore, class Buffering, class Coherence>
@ -267,6 +265,7 @@ template<class TagStore, class Buffering, class Coherence>
Packet *
Cache<TagStore,Buffering,Coherence>::getPacket()
{
assert(missQueue->havePending());
Packet * pkt = missQueue->getPacket();
if (pkt) {
if (!pkt->req->isUncacheable()) {
@ -292,7 +291,17 @@ Cache<TagStore,Buffering,Coherence>::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<uint8_t>(), 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<TagStore,Buffering,Coherence>::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<TagStore,Buffering,Coherence>::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<TagStore,Buffering,Coherence>::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<TagStore,Buffering,Coherence>::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<TagStore,Buffering,Coherence>::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;
}

View file

@ -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;
}

View file

@ -100,6 +100,7 @@ MSHR::deallocate()
{
assert(targets.empty());
assert(ntargets == 0);
delete pkt;
pkt = NULL;
inService = false;
//allocIter = NULL;

View file

@ -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;

View file

@ -59,8 +59,8 @@ typedef std::list<PacketPtr> 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

View file

@ -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"