mem-cache: Determine if an MSHR has requests from another cache
authorNikos Nikoleris <nikos.nikoleris@arm.com>
Wed, 2 May 2018 13:41:22 +0000 (14:41 +0100)
committerNikos Nikoleris <nikos.nikoleris@arm.com>
Wed, 30 May 2018 13:08:55 +0000 (13:08 +0000)
To decide whether we allocate upon receiving a response we need to
determine if any of the currently serviced requests (non-deferred
targets) is comming from another cache. This change adds support for
tracking this information in the MSHR.

Change-Id: If1db93c12b6af5813b91b9d6b6e5e196d327f038
Reviewed-on: https://gem5-review.googlesource.com/10422
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>

src/mem/cache/cache.cc
src/mem/cache/mshr.cc
src/mem/cache/mshr.hh

index 73c7e1956ad6384df0acd3d879d734aa02ef5527..e9aec499a061084e9f424d86284016d44a77d885 100644 (file)
@@ -1415,7 +1415,6 @@ Cache::recvTimingResp(PacketPtr pkt)
     // First offset for critical word first calculations
     int initial_offset = initial_tgt->pkt->getOffset(blkSize);
 
-    bool from_cache = false;
     MSHR::TargetList targets = mshr->extractServiceableTargets(pkt);
     for (auto &target: targets) {
         Packet *tgt_pkt = target.pkt;
@@ -1437,10 +1436,6 @@ Cache::recvTimingResp(PacketPtr pkt)
                 break; // skip response
             }
 
-            // keep track of whether we have responded to another
-            // cache
-            from_cache = from_cache || tgt_pkt->fromCache();
-
             // unlike the other packet flows, where data is found in other
             // caches or memory and brought back, write-line requests always
             // have the data right away, so the above check for "is fill?"
@@ -1572,7 +1567,7 @@ Cache::recvTimingResp(PacketPtr pkt)
         }
     }
 
-    maintainClusivity(from_cache, blk);
+    maintainClusivity(targets.hasFromCache, blk);
 
     if (blk && blk->isValid()) {
         // an invalidate response stemming from a write line request
index cc26b56514c8731bf56117ecad040a5c75e51634..4f170e6b3a036208a821266154c4a3a554ac89ed 100644 (file)
@@ -68,7 +68,8 @@ MSHR::MSHR() : downstreamPending(false),
 }
 
 MSHR::TargetList::TargetList()
-    : needsWritable(false), hasUpgrade(false), allocOnFill(false)
+    : needsWritable(false), hasUpgrade(false), allocOnFill(false),
+      hasFromCache(false)
 {}
 
 
@@ -91,6 +92,10 @@ MSHR::TargetList::updateFlags(PacketPtr pkt, Target::Source source,
         // potentially re-evaluate whether we should allocate on a fill or
         // not
         allocOnFill = allocOnFill || alloc_on_fill;
+
+        if (source != Target::FromPrefetcher) {
+            hasFromCache = hasFromCache || pkt->fromCache();
+        }
     }
 }
 
@@ -590,7 +595,7 @@ MSHR::sendPacket(Cache &cache)
 void
 MSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const
 {
-    ccprintf(os, "%s[%#llx:%#llx](%s) %s %s %s state: %s %s %s %s %s\n",
+    ccprintf(os, "%s[%#llx:%#llx](%s) %s %s %s state: %s %s %s %s %s %s\n",
              prefix, blkAddr, blkAddr + blkSize - 1,
              isSecure ? "s" : "ns",
              isForward ? "Forward" : "",
@@ -600,7 +605,8 @@ MSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const
              inService ? "InSvc" : "",
              downstreamPending ? "DwnPend" : "",
              postInvalidate ? "PostInv" : "",
-             postDowngrade ? "PostDowngr" : "");
+             postDowngrade ? "PostDowngr" : "",
+             hasFromCache() ? "HasFromCache" : "");
 
     if (!targets.empty()) {
         ccprintf(os, "%s  Targets:\n", prefix);
index 5fe0fb92d75664ebcd38b9ed30815b7cafd1da03..b4bf33a4fb669fd5403329532542d134fafb3a89 100644 (file)
@@ -162,6 +162,11 @@ class MSHR : public QueueEntry, public Printable
         bool hasUpgrade;
         /** Set when the response should allocate on fill */
         bool allocOnFill;
+        /**
+         * Determine whether there was at least one non-snooping
+         * target coming from another cache.
+         */
+        bool hasFromCache;
 
         TargetList();
 
@@ -176,7 +181,12 @@ class MSHR : public QueueEntry, public Printable
         void updateFlags(PacketPtr pkt, Target::Source source,
                          bool alloc_on_fill);
 
-        void resetFlags() { needsWritable = hasUpgrade = allocOnFill = false; }
+        void resetFlags() {
+            needsWritable = false;
+            hasUpgrade = false;
+            allocOnFill = false;
+            hasFromCache = false;
+        }
 
         /**
          * Goes through the list of targets and uses them to populate
@@ -191,7 +201,8 @@ class MSHR : public QueueEntry, public Printable
          * values.
          */
         bool isReset() const {
-            return !needsWritable && !hasUpgrade && !allocOnFill;
+            return !needsWritable && !hasUpgrade && !allocOnFill &&
+                !hasFromCache;
         }
 
         /**
@@ -257,6 +268,16 @@ class MSHR : public QueueEntry, public Printable
     bool allocOnFill() const {
         return targets.allocOnFill;
     }
+
+    /**
+     * Determine if there are non-deferred requests from other caches
+     *
+     * @return true if any of the targets is from another cache
+     */
+    bool hasFromCache() const {
+        return targets.hasFromCache;
+    }
+
   private:
 
     /**