Mark cache-to-cache MSHRs as downstreamPending when necessary.
authorSteve Reinhardt <stever@gmail.com>
Wed, 2 Jan 2008 23:18:33 +0000 (15:18 -0800)
committerSteve Reinhardt <stever@gmail.com>
Wed, 2 Jan 2008 23:18:33 +0000 (15:18 -0800)
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
src/mem/cache/miss/mshr.hh

index 88d2acea0cc1e216df73ff78735efb2ac9abd90b..d711ca53779d2b4e961101dbc63053dc5c4a5978 100644 (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();
index 0bc3c44806faf52dc46b75fb3be4a883487d72f5..fdb0485cb5d61f9e772ee1e6a7076e973c8ddbbb 100644 (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.
      */