mem-cache: Copy over flags to forwarded response
authorNikos Nikoleris <nikos.nikoleris@arm.com>
Tue, 22 Jan 2019 17:40:17 +0000 (17:40 +0000)
committerNikos Nikoleris <nikos.nikoleris@arm.com>
Tue, 26 Feb 2019 11:17:58 +0000 (11:17 +0000)
A cache that forwards a request to the memory below does not fill and
forwards the response with the data to cache above. This change
ensures that the flags of the original response are also preserved.

Change-Id: I244b20b073c31b976358816c5b14bba413b8271f
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/16182
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
src/mem/cache/cache.cc
src/mem/packet.cc
src/mem/packet.hh

index e23c4ef30b71a4ed87d7064dea36e73ef28e39db..89e40f328517dd62e6efb8d8f3e0f1850c18ba45 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2018 ARM Limited
+ * Copyright (c) 2010-2019 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -786,6 +786,11 @@ Cache::serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk)
 
                     tgt_pkt->setData(pkt->getConstPtr<uint8_t>());
                 }
+
+                // this response did not allocate here and therefore
+                // it was not consumed, make sure that any flags are
+                // carried over to cache above
+                tgt_pkt->copyResponderFlags(pkt);
             }
             tgt_pkt->makeTimingResponse();
             // if this packet is an error copy that to the new packet
@@ -965,7 +970,6 @@ Cache::handleSnoop(PacketPtr pkt, CacheBlk *blk, bool is_timing,
         // first propagate snoop upward to see if anyone above us wants to
         // handle it.  save & restore packet src since it will get
         // rewritten to be relative to cpu-side bus (if any)
-        bool alreadyResponded = pkt->cacheResponding();
         if (is_timing) {
             // copy the packet so that we can clear any flags before
             // forwarding it upwards, we also allocate data (passing
@@ -983,16 +987,6 @@ Cache::handleSnoop(PacketPtr pkt, CacheBlk *blk, bool is_timing,
             // cache
             snoop_delay += snoopPkt.headerDelay;
 
-            if (snoopPkt.cacheResponding()) {
-                // cache-to-cache response from some upper cache
-                assert(!alreadyResponded);
-                pkt->setCacheResponding();
-            }
-            // upstream cache has the block, or has an outstanding
-            // MSHR, pass the flag on
-            if (snoopPkt.hasSharers()) {
-                pkt->setHasSharers();
-            }
             // If this request is a prefetch or clean evict and an upper level
             // signals block present, make sure to propagate the block
             // presence to the requester.
@@ -1004,9 +998,14 @@ Cache::handleSnoop(PacketPtr pkt, CacheBlk *blk, bool is_timing,
             if (snoopPkt.satisfied()) {
                 pkt->setSatisfied();
             }
+
+            // Copy over flags from the snoop response to make sure we
+            // inform the final destination
+            pkt->copyResponderFlags(&snoopPkt);
         } else {
+            bool already_responded = pkt->cacheResponding();
             cpuSidePort.sendAtomicSnoop(pkt);
-            if (!alreadyResponded && pkt->cacheResponding()) {
+            if (!already_responded && pkt->cacheResponding()) {
                 // cache-to-cache response from some upper cache:
                 // forward response to original requester
                 assert(pkt->isResponse());
index 4369e168ff75ce2d3aed5655fb1c08d256fd2851..e1c760cd05c95a4b1ad3ee78232af85e186d6d2d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2018 ARM Limited
+ * Copyright (c) 2011-2019 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -302,6 +302,16 @@ Packet::trySatisfyFunctional(Printable *obj, Addr addr, bool is_secure, int size
     return false;
 }
 
+void
+Packet::copyResponderFlags(const PacketPtr pkt)
+{
+    assert(isRequest());
+    // If we have already found a responder, no other cache should
+    // commit to responding
+    assert(!pkt->cacheResponding() || !cacheResponding());
+    flags.set(pkt->flags & RESPONDER_FLAGS);
+}
+
 void
 Packet::pushSenderState(Packet::SenderState *sender_state)
 {
index c59db362e2807ce4928bc2ffda55f0efb7f515e2..2bcbf4dab39c8d24bc714f82a73611f28b2121e4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018 ARM Limited
+ * Copyright (c) 2012-2019 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -265,6 +265,9 @@ class Packet : public Printable
         // Flags to transfer across when copying a packet
         COPY_FLAGS             = 0x0000003F,
 
+        // Flags that are used to create reponse packets
+        RESPONDER_FLAGS        = 0x00000009,
+
         // Does this packet have sharers (which means it should not be
         // considered writable) or not. See setHasSharers below.
         HAS_SHARERS            = 0x00000001,
@@ -649,6 +652,15 @@ class Packet : public Printable
     bool responderHadWritable() const
     { return flags.isSet(RESPONDER_HAD_WRITABLE); }
 
+    /**
+     * Copy the reponse flags from an input packet to this packet. The
+     * reponse flags determine whether a responder has been found and
+     * the state at which the block will be at the destination.
+     *
+     * @pkt The packet that we will copy flags from
+     */
+    void copyResponderFlags(const PacketPtr pkt);
+
     /**
      * A writeback/writeclean cmd gets propagated further downstream
      * by the receiver when the flag is set.