From bf9b3821bda5f534a44b176c0ed738a17cb9b80a Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Wed, 2 Jan 2008 15:18:33 -0800 Subject: [PATCH] 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 --- src/mem/cache/miss/mshr.cc | 44 +++++++++++++++++++++++++++----------- src/mem/cache/miss/mshr.hh | 12 ++++++++--- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/mem/cache/miss/mshr.cc b/src/mem/cache/miss/mshr.cc index 88d2acea0..d711ca537 100644 --- a/src/mem/cache/miss/mshr.cc +++ b/src/mem/cache/miss/mshr.cc @@ -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(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(i->pkt->senderState); - if (mshr != NULL) { - assert(mshr->downstreamPending); - mshr->downstreamPending = false; + if (i->markedPending) { + MSHR *mshr = dynamic_cast(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(); diff --git a/src/mem/cache/miss/mshr.hh b/src/mem/cache/miss/mshr.hh index 0bc3c4480..fdb0485cb 100644 --- a/src/mem/cache/miss/mshr.hh +++ b/src/mem/cache/miss/mshr.hh @@ -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. */ -- 2.30.2