Mark cache-to-cache MSHRs as downstreamPending when necessary.

Don't mark upstream MSHR as pending if downstream MSHR is already in service.

--HG--
extra : convert_revision : e1c135ff00217291db58ce8a06ccde34c403d37f
This commit is contained in:
Steve Reinhardt
2008-01-02 15:18:33 -08:00
parent 538da9e24d
commit bf9b3821bd
2 changed files with 41 additions and 15 deletions

View File

@@ -64,7 +64,7 @@ MSHR::TargetList::TargetList()
inline void
MSHR::TargetList::add(PacketPtr pkt, Tick readyTime,
Counter order, bool cpuSide)
Counter order, bool cpuSide, bool markPending)
{
if (cpuSide) {
if (pkt->needsExclusive()) {
@@ -74,7 +74,9 @@ MSHR::TargetList::add(PacketPtr pkt, Tick readyTime,
if (pkt->cmd == MemCmd::UpgradeReq) {
hasUpgrade = true;
}
}
if (markPending) {
MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState);
if (mshr != NULL) {
assert(!mshr->downstreamPending);
@@ -82,7 +84,7 @@ MSHR::TargetList::add(PacketPtr pkt, Tick readyTime,
}
}
push_back(Target(pkt, readyTime, order, cpuSide));
push_back(Target(pkt, readyTime, order, cpuSide, markPending));
}
@@ -109,10 +111,11 @@ 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;
if (i->markedPending) {
MSHR *mshr = dynamic_cast<MSHR*>(i->pkt->senderState);
if (mshr != NULL) {
mshr->clearDownstreamPending();
}
}
}
}
@@ -162,7 +165,7 @@ MSHR::allocate(Addr _addr, int _size, PacketPtr target,
// Don't know of a case where we would allocate a new MSHR for a
// snoop (mem-side request), so set cpuSide to true here.
assert(targets->isReset());
targets->add(target, whenReady, _order, true);
targets->add(target, whenReady, _order, true, true);
assert(deferredTargets->isReset());
pendingInvalidate = false;
pendingShared = false;
@@ -170,6 +173,16 @@ MSHR::allocate(Addr _addr, int _size, PacketPtr target,
}
void
MSHR::clearDownstreamPending()
{
assert(downstreamPending);
downstreamPending = false;
// recursively clear flag on any MSHRs we will be forwarding
// responses to
targets->clearDownstreamPending();
}
bool
MSHR::markInService()
{
@@ -221,11 +234,13 @@ MSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order)
(!deferredTargets->empty() || pendingInvalidate ||
(!targets->needsExclusive && pkt->needsExclusive()))) {
// need to put on deferred list
deferredTargets->add(pkt, whenReady, _order, true);
deferredTargets->add(pkt, whenReady, _order, true, true);
} else {
// no request outstanding, or still OK to append to
// outstanding request
targets->add(pkt, whenReady, _order, true);
// No request outstanding, or still OK to append to
// outstanding request: append to regular target list. Only
// mark pending if current request hasn't been issued yet
// (isn't in service).
targets->add(pkt, whenReady, _order, true, !inService);
}
++ntargets;
@@ -276,7 +291,8 @@ MSHR::handleSnoop(PacketPtr pkt, Counter _order)
// actual target device (typ. PhysicalMemory) will delete the
// packet on reception, so we need to save a copy here
PacketPtr cp_pkt = new Packet(pkt, true);
targets->add(cp_pkt, curTick, _order, false);
targets->add(cp_pkt, curTick, _order, false,
downstreamPending && targets->needsExclusive);
++ntargets;
if (targets->needsExclusive) {
@@ -355,6 +371,10 @@ MSHR::handleFill(Packet *pkt, CacheBlk *blk)
// the regular target list.
assert(!targets->needsExclusive);
targets->needsExclusive = true;
// if any of the deferred targets were upper-level cache
// requests marked downstreamPending, need to clear that
assert(!downstreamPending); // not pending here anymore
deferredTargets->clearDownstreamPending();
// this clears out deferredTargets too
targets->splice(targets->end(), *deferredTargets);
deferredTargets->resetFlags();

View File

@@ -60,12 +60,15 @@ class MSHR : public Packet::SenderState, public Printable
Counter order; //!< Global order (for memory consistency mgmt)
PacketPtr pkt; //!< Pending request packet.
bool cpuSide; //!< Did request come from cpu side or mem side?
bool markedPending; //!< Did we mark upstream MSHR
//!< as downstreamPending?
bool isCpuSide() const { return cpuSide; }
Target(PacketPtr _pkt, Tick _readyTime, Counter _order, bool _cpuSide)
Target(PacketPtr _pkt, Tick _readyTime, Counter _order,
bool _cpuSide, bool _markedPending)
: recvTime(curTick), readyTime(_readyTime), order(_order),
pkt(_pkt), cpuSide(_cpuSide)
pkt(_pkt), cpuSide(_cpuSide), markedPending(_markedPending)
{}
};
@@ -81,7 +84,8 @@ class MSHR : public Packet::SenderState, public Printable
TargetList();
void resetFlags() { needsExclusive = hasUpgrade = false; }
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, bool markPending);
void replaceUpgrades();
void clearDownstreamPending();
bool checkFunctional(PacketPtr pkt);
@@ -173,6 +177,8 @@ public:
bool markInService();
void clearDownstreamPending();
/**
* Mark this MSHR as free.
*/