Replace lowerMSHRPending flag with more robust scheme
based on following Packet senderState links. --HG-- extra : convert_revision : 9027d59bd7242aa0e4275bf94d8b1fb27bd59d79
This commit is contained in:
parent
fe442f67ad
commit
82e2a35576
6 changed files with 60 additions and 37 deletions
3
src/mem/cache/cache.hh
vendored
3
src/mem/cache/cache.hh
vendored
|
@ -190,8 +190,7 @@ class Cache : public BaseCache
|
||||||
* @param new_state The new coherence state for the block.
|
* @param new_state The new coherence state for the block.
|
||||||
*/
|
*/
|
||||||
void handleSnoop(PacketPtr ptk, BlkType *blk,
|
void handleSnoop(PacketPtr ptk, BlkType *blk,
|
||||||
bool is_timing, bool is_deferred,
|
bool is_timing, bool is_deferred);
|
||||||
bool lower_mshr_pending);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a writeback request for the given block.
|
* Create a writeback request for the given block.
|
||||||
|
|
22
src/mem/cache/cache_impl.hh
vendored
22
src/mem/cache/cache_impl.hh
vendored
|
@ -754,7 +754,7 @@ Cache<TagStore>::handleResponse(PacketPtr pkt)
|
||||||
} else {
|
} else {
|
||||||
// response to snoop request
|
// response to snoop request
|
||||||
DPRINTF(Cache, "processing deferred snoop...\n");
|
DPRINTF(Cache, "processing deferred snoop...\n");
|
||||||
handleSnoop(target->pkt, blk, true, true, false);
|
handleSnoop(target->pkt, blk, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
mshr->popTarget();
|
mshr->popTarget();
|
||||||
|
@ -917,8 +917,7 @@ Cache<TagStore>::doTimingSupplyResponse(PacketPtr req_pkt,
|
||||||
template<class TagStore>
|
template<class TagStore>
|
||||||
void
|
void
|
||||||
Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk,
|
Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk,
|
||||||
bool is_timing, bool is_deferred,
|
bool is_timing, bool is_deferred)
|
||||||
bool lower_mshr_pending)
|
|
||||||
{
|
{
|
||||||
assert(pkt->isRequest());
|
assert(pkt->isRequest());
|
||||||
|
|
||||||
|
@ -930,9 +929,6 @@ Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk,
|
||||||
if (is_timing) {
|
if (is_timing) {
|
||||||
Packet *snoopPkt = new Packet(pkt, true); // clear flags
|
Packet *snoopPkt = new Packet(pkt, true); // clear flags
|
||||||
snoopPkt->setExpressSnoop();
|
snoopPkt->setExpressSnoop();
|
||||||
if (lower_mshr_pending) {
|
|
||||||
snoopPkt->setLowerMSHRPending();
|
|
||||||
}
|
|
||||||
snoopPkt->senderState = new ForwardResponseRecord(pkt, this);
|
snoopPkt->senderState = new ForwardResponseRecord(pkt, this);
|
||||||
cpuSidePort->sendTiming(snoopPkt);
|
cpuSidePort->sendTiming(snoopPkt);
|
||||||
if (snoopPkt->memInhibitAsserted()) {
|
if (snoopPkt->memInhibitAsserted()) {
|
||||||
|
@ -1019,16 +1015,6 @@ Cache<TagStore>::snoopTiming(PacketPtr pkt)
|
||||||
Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
|
Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
|
||||||
MSHR *mshr = mshrQueue.findMatch(blk_addr);
|
MSHR *mshr = mshrQueue.findMatch(blk_addr);
|
||||||
|
|
||||||
// If a lower cache has an operation on this block pending (not
|
|
||||||
// yet in service) on the MSHR, then the upper caches need to know
|
|
||||||
// about it, as this means that the pending operation logically
|
|
||||||
// succeeds the current snoop. It's not sufficient to record
|
|
||||||
// whether the MSHR *is* in service, as this misses the window
|
|
||||||
// where the lower cache has completed the request and the
|
|
||||||
// response is on its way back up the hierarchy.
|
|
||||||
bool lower_mshr_pending =
|
|
||||||
(mshr && (!mshr->inService) || pkt->lowerMSHRPending());
|
|
||||||
|
|
||||||
// Let the MSHR itself track the snoop and decide whether we want
|
// Let the MSHR itself track the snoop and decide whether we want
|
||||||
// to go ahead and do the regular cache snoop
|
// to go ahead and do the regular cache snoop
|
||||||
if (mshr && mshr->handleSnoop(pkt, order++)) {
|
if (mshr && mshr->handleSnoop(pkt, order++)) {
|
||||||
|
@ -1075,7 +1061,7 @@ Cache<TagStore>::snoopTiming(PacketPtr pkt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSnoop(pkt, blk, true, false, lower_mshr_pending);
|
handleSnoop(pkt, blk, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1090,7 +1076,7 @@ Cache<TagStore>::snoopAtomic(PacketPtr pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
BlkType *blk = tags->findBlock(pkt->getAddr());
|
BlkType *blk = tags->findBlock(pkt->getAddr());
|
||||||
handleSnoop(pkt, blk, false, false, false);
|
handleSnoop(pkt, blk, false, false);
|
||||||
return hitLatency;
|
return hitLatency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
48
src/mem/cache/miss/mshr.cc
vendored
48
src/mem/cache/miss/mshr.cc
vendored
|
@ -63,7 +63,8 @@ MSHR::TargetList::TargetList()
|
||||||
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
MSHR::TargetList::add(PacketPtr pkt, Tick readyTime, Counter order, bool cpuSide)
|
MSHR::TargetList::add(PacketPtr pkt, Tick readyTime,
|
||||||
|
Counter order, bool cpuSide)
|
||||||
{
|
{
|
||||||
if (cpuSide) {
|
if (cpuSide) {
|
||||||
if (pkt->needsExclusive()) {
|
if (pkt->needsExclusive()) {
|
||||||
|
@ -73,6 +74,12 @@ MSHR::TargetList::add(PacketPtr pkt, Tick readyTime, Counter order, bool cpuSide
|
||||||
if (pkt->cmd == MemCmd::UpgradeReq) {
|
if (pkt->cmd == MemCmd::UpgradeReq) {
|
||||||
hasUpgrade = true;
|
hasUpgrade = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState);
|
||||||
|
if (mshr != NULL) {
|
||||||
|
assert(!mshr->downstreamPending);
|
||||||
|
mshr->downstreamPending = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
push_back(Target(pkt, readyTime, order, cpuSide));
|
push_back(Target(pkt, readyTime, order, cpuSide));
|
||||||
|
@ -97,6 +104,20 @@ MSHR::TargetList::replaceUpgrades()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MSHR::TargetList::clearDownstreamPending()
|
||||||
|
{
|
||||||
|
Iterator end_i = end();
|
||||||
|
for (Iterator i = begin(); i != end_i; ++i) {
|
||||||
|
MSHR *mshr = dynamic_cast<MSHR*>(i->pkt->senderState);
|
||||||
|
if (mshr != NULL) {
|
||||||
|
assert(mshr->downstreamPending);
|
||||||
|
mshr->downstreamPending = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MSHR::allocate(Addr _addr, int _size, PacketPtr target,
|
MSHR::allocate(Addr _addr, int _size, PacketPtr target,
|
||||||
Tick whenReady, Counter _order)
|
Tick whenReady, Counter _order)
|
||||||
|
@ -109,6 +130,7 @@ MSHR::allocate(Addr _addr, int _size, PacketPtr target,
|
||||||
isCacheFill = false;
|
isCacheFill = false;
|
||||||
_isUncacheable = target->req->isUncacheable();
|
_isUncacheable = target->req->isUncacheable();
|
||||||
inService = false;
|
inService = false;
|
||||||
|
downstreamPending = false;
|
||||||
threadNum = 0;
|
threadNum = 0;
|
||||||
ntargets = 1;
|
ntargets = 1;
|
||||||
// Don't know of a case where we would allocate a new MSHR for a
|
// Don't know of a case where we would allocate a new MSHR for a
|
||||||
|
@ -121,6 +143,28 @@ MSHR::allocate(Addr _addr, int _size, PacketPtr target,
|
||||||
data = NULL;
|
data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
MSHR::markInService()
|
||||||
|
{
|
||||||
|
assert(!inService);
|
||||||
|
if (isSimpleForward()) {
|
||||||
|
// we just forwarded the request packet & don't expect a
|
||||||
|
// response, so get rid of it
|
||||||
|
assert(getNumTargets() == 1);
|
||||||
|
popTarget();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
inService = true;
|
||||||
|
if (!downstreamPending) {
|
||||||
|
// let upstream caches know that the request has made it to a
|
||||||
|
// level where it's going to get a response
|
||||||
|
targets->clearDownstreamPending();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MSHR::deallocate()
|
MSHR::deallocate()
|
||||||
{
|
{
|
||||||
|
@ -164,7 +208,7 @@ MSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order)
|
||||||
bool
|
bool
|
||||||
MSHR::handleSnoop(PacketPtr pkt, Counter _order)
|
MSHR::handleSnoop(PacketPtr pkt, Counter _order)
|
||||||
{
|
{
|
||||||
if (!inService || (pkt->isExpressSnoop() && pkt->lowerMSHRPending())) {
|
if (!inService || downstreamPending) {
|
||||||
// Request has not been issued yet, or it's been issued
|
// Request has not been issued yet, or it's been issued
|
||||||
// locally but is buffered unissued at some downstream cache
|
// locally but is buffered unissued at some downstream cache
|
||||||
// which is forwarding us this snoop. Either way, the packet
|
// which is forwarding us this snoop. Either way, the packet
|
||||||
|
|
5
src/mem/cache/miss/mshr.hh
vendored
5
src/mem/cache/miss/mshr.hh
vendored
|
@ -81,6 +81,7 @@ class MSHR : public Packet::SenderState
|
||||||
bool isReset() { return !needsExclusive && !hasUpgrade; }
|
bool isReset() { return !needsExclusive && !hasUpgrade; }
|
||||||
void add(PacketPtr pkt, Tick readyTime, Counter order, bool cpuSide);
|
void add(PacketPtr pkt, Tick readyTime, Counter order, bool cpuSide);
|
||||||
void replaceUpgrades();
|
void replaceUpgrades();
|
||||||
|
void clearDownstreamPending();
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A list of MSHRs. */
|
/** A list of MSHRs. */
|
||||||
|
@ -117,6 +118,8 @@ class MSHR : public Packet::SenderState
|
||||||
/** True if the request is uncacheable */
|
/** True if the request is uncacheable */
|
||||||
bool _isUncacheable;
|
bool _isUncacheable;
|
||||||
|
|
||||||
|
bool downstreamPending;
|
||||||
|
|
||||||
bool pendingInvalidate;
|
bool pendingInvalidate;
|
||||||
bool pendingShared;
|
bool pendingShared;
|
||||||
|
|
||||||
|
@ -163,6 +166,8 @@ public:
|
||||||
void allocate(Addr addr, int size, PacketPtr pkt,
|
void allocate(Addr addr, int size, PacketPtr pkt,
|
||||||
Tick when, Counter _order);
|
Tick when, Counter _order);
|
||||||
|
|
||||||
|
bool markInService();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark this MSHR as free.
|
* Mark this MSHR as free.
|
||||||
*/
|
*/
|
||||||
|
|
16
src/mem/cache/miss/mshr_queue.cc
vendored
16
src/mem/cache/miss/mshr_queue.cc
vendored
|
@ -179,20 +179,12 @@ MSHRQueue::moveToFront(MSHR *mshr)
|
||||||
void
|
void
|
||||||
MSHRQueue::markInService(MSHR *mshr)
|
MSHRQueue::markInService(MSHR *mshr)
|
||||||
{
|
{
|
||||||
assert(!mshr->inService);
|
if (mshr->markInService()) {
|
||||||
if (mshr->isSimpleForward()) {
|
|
||||||
// we just forwarded the request packet & don't expect a
|
|
||||||
// response, so get rid of it
|
|
||||||
assert(mshr->getNumTargets() == 1);
|
|
||||||
mshr->popTarget();
|
|
||||||
deallocate(mshr);
|
deallocate(mshr);
|
||||||
return;
|
} else {
|
||||||
|
readyList.erase(mshr->readyIter);
|
||||||
|
inServiceEntries += 1;
|
||||||
}
|
}
|
||||||
mshr->inService = true;
|
|
||||||
readyList.erase(mshr->readyIter);
|
|
||||||
//mshr->readyIter = NULL;
|
|
||||||
inServiceEntries += 1;
|
|
||||||
//readyList.pop_front();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -257,7 +257,6 @@ class Packet : public FastAlloc
|
||||||
Shared,
|
Shared,
|
||||||
// Special control flags
|
// Special control flags
|
||||||
ExpressSnoop,
|
ExpressSnoop,
|
||||||
LowerMSHRPending, // not yet in service
|
|
||||||
NUM_PACKET_FLAGS
|
NUM_PACKET_FLAGS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -323,8 +322,6 @@ class Packet : public FastAlloc
|
||||||
// Special control flags
|
// Special control flags
|
||||||
void setExpressSnoop() { flags[ExpressSnoop] = true; }
|
void setExpressSnoop() { flags[ExpressSnoop] = true; }
|
||||||
bool isExpressSnoop() { return flags[ExpressSnoop]; }
|
bool isExpressSnoop() { return flags[ExpressSnoop]; }
|
||||||
void setLowerMSHRPending() { flags[LowerMSHRPending] = true; }
|
|
||||||
bool lowerMSHRPending() { return flags[LowerMSHRPending]; }
|
|
||||||
|
|
||||||
// Network error conditions... encapsulate them as methods since
|
// Network error conditions... encapsulate them as methods since
|
||||||
// their encoding keeps changing (from result field to command
|
// their encoding keeps changing (from result field to command
|
||||||
|
|
Loading…
Reference in a new issue