Fixes for blocking in the caches that needed to be pulled
src/mem/cache/base_cache.cc: Add in retry path for blocking with multi-level caches src/mem/cache/base_cache.hh: Pull more of the blocking fixes into head src/mem/packet.hh: Fix typo --HG-- extra : convert_revision : d4d149adfa414136ebd2c4789b739bb065710f7a
This commit is contained in:
parent
890f0fc782
commit
8a82553aec
3 changed files with 71 additions and 11 deletions
56
src/mem/cache/base_cache.cc
vendored
56
src/mem/cache/base_cache.cc
vendored
|
@ -73,6 +73,7 @@ BaseCache::CachePort::recvTiming(Packet *pkt)
|
|||
{
|
||||
if (blocked)
|
||||
{
|
||||
DPRINTF(Cache,"Scheduling a retry while blocked\n");
|
||||
mustSendRetry = true;
|
||||
return false;
|
||||
}
|
||||
|
@ -91,21 +92,63 @@ BaseCache::CachePort::recvFunctional(Packet *pkt)
|
|||
cache->doFunctionalAccess(pkt, isCpuSide);
|
||||
}
|
||||
|
||||
void
|
||||
BaseCache::CachePort::recvRetry()
|
||||
{
|
||||
Packet *pkt;
|
||||
|
||||
if (!isCpuSide)
|
||||
{
|
||||
pkt = cache->getPacket();
|
||||
bool success = sendTiming(pkt);
|
||||
DPRINTF(Cache, "Address %x was %s in sending the timing request\n",
|
||||
pkt->getAddr(), success ? "succesful" : "unsuccesful");
|
||||
cache->sendResult(pkt, success);
|
||||
if (success && cache->doMasterRequest())
|
||||
{
|
||||
//Still more to issue, rerequest in 1 cycle
|
||||
pkt = NULL;
|
||||
BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this);
|
||||
reqCpu->schedule(curTick + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pkt = cache->getCoherencePacket();
|
||||
bool success = sendTiming(pkt);
|
||||
if (success && cache->doSlaveRequest())
|
||||
{
|
||||
//Still more to issue, rerequest in 1 cycle
|
||||
pkt = NULL;
|
||||
BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this);
|
||||
reqCpu->schedule(curTick + 1);
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
void
|
||||
BaseCache::CachePort::setBlocked()
|
||||
{
|
||||
assert(!blocked);
|
||||
DPRINTF(Cache, "Cache Blocking\n");
|
||||
blocked = true;
|
||||
//Clear the retry flag
|
||||
mustSendRetry = false;
|
||||
}
|
||||
|
||||
void
|
||||
BaseCache::CachePort::clearBlocked()
|
||||
{
|
||||
assert(blocked);
|
||||
DPRINTF(Cache, "Cache Unblocking\n");
|
||||
blocked = false;
|
||||
if (mustSendRetry)
|
||||
{
|
||||
DPRINTF(Cache, "Cache Sending Retry\n");
|
||||
mustSendRetry = false;
|
||||
sendRetry();
|
||||
}
|
||||
blocked = false;
|
||||
}
|
||||
|
||||
BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort)
|
||||
|
@ -128,6 +171,7 @@ BaseCache::CacheEvent::process()
|
|||
{
|
||||
if (!cachePort->isCpuSide)
|
||||
{
|
||||
//MSHR
|
||||
pkt = cachePort->cache->getPacket();
|
||||
bool success = cachePort->sendTiming(pkt);
|
||||
DPRINTF(Cache, "Address %x was %s in sending the timing request\n",
|
||||
|
@ -142,11 +186,19 @@ BaseCache::CacheEvent::process()
|
|||
}
|
||||
else
|
||||
{
|
||||
//CSHR
|
||||
pkt = cachePort->cache->getCoherencePacket();
|
||||
cachePort->sendTiming(pkt);
|
||||
bool success = cachePort->sendTiming(pkt);
|
||||
if (success && cachePort->cache->doSlaveRequest())
|
||||
{
|
||||
//Still more to issue, rerequest in 1 cycle
|
||||
pkt = NULL;
|
||||
this->schedule(curTick+1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//Response
|
||||
//Know the packet to send, no need to mark in service (must succed)
|
||||
bool success = cachePort->sendTiming(pkt);
|
||||
assert(success);
|
||||
|
|
24
src/mem/cache/base_cache.hh
vendored
24
src/mem/cache/base_cache.hh
vendored
|
@ -98,6 +98,8 @@ class BaseCache : public MemObject
|
|||
|
||||
virtual int deviceBlockSize();
|
||||
|
||||
virtual void recvRetry();
|
||||
|
||||
public:
|
||||
void setBlocked();
|
||||
|
||||
|
@ -407,17 +409,23 @@ class BaseCache : public MemObject
|
|||
void clearBlocked(BlockedCause cause)
|
||||
{
|
||||
uint8_t flag = 1 << cause;
|
||||
blocked &= ~flag;
|
||||
blockedSnoop &= ~flag;
|
||||
DPRINTF(Cache,"Unblocking for cause %s, causes left=%i\n",
|
||||
cause, blocked);
|
||||
if (!isBlocked()) {
|
||||
blocked_cycles[cause] += curTick - blockedCycle;
|
||||
DPRINTF(Cache,"Unblocking from all causes\n");
|
||||
cpuSidePort->clearBlocked();
|
||||
if (blocked & flag)
|
||||
{
|
||||
blocked &= ~flag;
|
||||
if (!isBlocked()) {
|
||||
blocked_cycles[cause] += curTick - blockedCycle;
|
||||
DPRINTF(Cache,"Unblocking from all causes\n");
|
||||
cpuSidePort->clearBlocked();
|
||||
}
|
||||
}
|
||||
if (!isBlockedForSnoop()) {
|
||||
memSidePort->clearBlocked();
|
||||
if (blockedSnoop & flag)
|
||||
{
|
||||
blockedSnoop &= ~flag;
|
||||
if (!isBlockedForSnoop()) {
|
||||
memSidePort->clearBlocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ class Packet
|
|||
bool isRequest() { return (cmd & IsRequest) != 0; }
|
||||
bool isResponse() { return (cmd & IsResponse) != 0; }
|
||||
bool needsResponse() { return (cmd & NeedsResponse) != 0; }
|
||||
bool isInvalidate() { return (cmd * IsInvalidate) != 0; }
|
||||
bool isInvalidate() { return (cmd & IsInvalidate) != 0; }
|
||||
|
||||
bool isCacheFill() { return (flags & CACHE_LINE_FILL) != 0; }
|
||||
bool isNoAllocate() { return (flags & NO_ALLOCATE) != 0; }
|
||||
|
|
Loading…
Reference in a new issue