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)
|
if (blocked)
|
||||||
{
|
{
|
||||||
|
DPRINTF(Cache,"Scheduling a retry while blocked\n");
|
||||||
mustSendRetry = true;
|
mustSendRetry = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -91,21 +92,63 @@ BaseCache::CachePort::recvFunctional(Packet *pkt)
|
||||||
cache->doFunctionalAccess(pkt, isCpuSide);
|
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
|
void
|
||||||
BaseCache::CachePort::setBlocked()
|
BaseCache::CachePort::setBlocked()
|
||||||
{
|
{
|
||||||
|
assert(!blocked);
|
||||||
|
DPRINTF(Cache, "Cache Blocking\n");
|
||||||
blocked = true;
|
blocked = true;
|
||||||
|
//Clear the retry flag
|
||||||
|
mustSendRetry = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BaseCache::CachePort::clearBlocked()
|
BaseCache::CachePort::clearBlocked()
|
||||||
{
|
{
|
||||||
|
assert(blocked);
|
||||||
|
DPRINTF(Cache, "Cache Unblocking\n");
|
||||||
|
blocked = false;
|
||||||
if (mustSendRetry)
|
if (mustSendRetry)
|
||||||
{
|
{
|
||||||
|
DPRINTF(Cache, "Cache Sending Retry\n");
|
||||||
mustSendRetry = false;
|
mustSendRetry = false;
|
||||||
sendRetry();
|
sendRetry();
|
||||||
}
|
}
|
||||||
blocked = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort)
|
BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort)
|
||||||
|
@ -128,6 +171,7 @@ BaseCache::CacheEvent::process()
|
||||||
{
|
{
|
||||||
if (!cachePort->isCpuSide)
|
if (!cachePort->isCpuSide)
|
||||||
{
|
{
|
||||||
|
//MSHR
|
||||||
pkt = cachePort->cache->getPacket();
|
pkt = cachePort->cache->getPacket();
|
||||||
bool success = cachePort->sendTiming(pkt);
|
bool success = cachePort->sendTiming(pkt);
|
||||||
DPRINTF(Cache, "Address %x was %s in sending the timing request\n",
|
DPRINTF(Cache, "Address %x was %s in sending the timing request\n",
|
||||||
|
@ -142,11 +186,19 @@ BaseCache::CacheEvent::process()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//CSHR
|
||||||
pkt = cachePort->cache->getCoherencePacket();
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
//Response
|
||||||
//Know the packet to send, no need to mark in service (must succed)
|
//Know the packet to send, no need to mark in service (must succed)
|
||||||
bool success = cachePort->sendTiming(pkt);
|
bool success = cachePort->sendTiming(pkt);
|
||||||
assert(success);
|
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 int deviceBlockSize();
|
||||||
|
|
||||||
|
virtual void recvRetry();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setBlocked();
|
void setBlocked();
|
||||||
|
|
||||||
|
@ -407,17 +409,23 @@ class BaseCache : public MemObject
|
||||||
void clearBlocked(BlockedCause cause)
|
void clearBlocked(BlockedCause cause)
|
||||||
{
|
{
|
||||||
uint8_t flag = 1 << cause;
|
uint8_t flag = 1 << cause;
|
||||||
blocked &= ~flag;
|
|
||||||
blockedSnoop &= ~flag;
|
|
||||||
DPRINTF(Cache,"Unblocking for cause %s, causes left=%i\n",
|
DPRINTF(Cache,"Unblocking for cause %s, causes left=%i\n",
|
||||||
cause, blocked);
|
cause, blocked);
|
||||||
if (!isBlocked()) {
|
if (blocked & flag)
|
||||||
blocked_cycles[cause] += curTick - blockedCycle;
|
{
|
||||||
DPRINTF(Cache,"Unblocking from all causes\n");
|
blocked &= ~flag;
|
||||||
cpuSidePort->clearBlocked();
|
if (!isBlocked()) {
|
||||||
|
blocked_cycles[cause] += curTick - blockedCycle;
|
||||||
|
DPRINTF(Cache,"Unblocking from all causes\n");
|
||||||
|
cpuSidePort->clearBlocked();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!isBlockedForSnoop()) {
|
if (blockedSnoop & flag)
|
||||||
memSidePort->clearBlocked();
|
{
|
||||||
|
blockedSnoop &= ~flag;
|
||||||
|
if (!isBlockedForSnoop()) {
|
||||||
|
memSidePort->clearBlocked();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ class Packet
|
||||||
bool isRequest() { return (cmd & IsRequest) != 0; }
|
bool isRequest() { return (cmd & IsRequest) != 0; }
|
||||||
bool isResponse() { return (cmd & IsResponse) != 0; }
|
bool isResponse() { return (cmd & IsResponse) != 0; }
|
||||||
bool needsResponse() { return (cmd & NeedsResponse) != 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 isCacheFill() { return (flags & CACHE_LINE_FILL) != 0; }
|
||||||
bool isNoAllocate() { return (flags & NO_ALLOCATE) != 0; }
|
bool isNoAllocate() { return (flags & NO_ALLOCATE) != 0; }
|
||||||
|
|
Loading…
Reference in a new issue