mem: Do not allocate space for packet data if not needed
authorAndreas Hansson <andreas.hansson@arm.com>
Thu, 31 Dec 2015 14:33:39 +0000 (09:33 -0500)
committerAndreas Hansson <andreas.hansson@arm.com>
Thu, 31 Dec 2015 14:33:39 +0000 (09:33 -0500)
This patch looks at the request and response command to determine if
either actually has any data payload, and if not, we do not allocate
any space for packet data.

The only tricky case is where the command type is changed as part of
the MSHR functionality. In these cases where the original packet had
no data, but the new packet does, we need to explicitly call
allocate().

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

index 991463d76a10ade41b0eeeb2eeb5ccb4dbb64fdf..9050a1c30ad4ad314ddbdfe87a07bdd9ef86cac4 100644 (file)
@@ -185,7 +185,11 @@ Cache::satisfyCpuSideRequest(PacketPtr pkt, CacheBlk *blk,
         if (pkt->isLLSC()) {
             blk->trackLoadLocked(pkt);
         }
+
+        // all read responses have a data payload
+        assert(pkt->hasRespData());
         pkt->setDataFromBlock(blk->data, blkSize);
+
         // determine if this read is from a (coherent) cache, or not
         // by looking at the command type; we could potentially add a
         // packet attribute such as 'FromCache' to make this check a
@@ -796,10 +800,7 @@ Cache::recvTimingReq(PacketPtr pkt)
             }
 
             pkt->makeTimingResponse();
-            // for debugging, set all the bits in the response data
-            // (also keeps valgrind from complaining when debugging settings
-            //  print out instruction results)
-            std::memset(pkt->getPtr<uint8_t>(), 0xFF, pkt->getSize());
+
             // request_time is used here, taking into account lat and the delay
             // charged if the packet comes from the xbar.
             cpuSidePort->schedTimingResp(pkt, request_time, true);
@@ -2041,7 +2042,10 @@ Cache::handleSnoop(PacketPtr pkt, CacheBlk *blk, bool is_timing,
             doTimingSupplyResponse(pkt, blk->data, is_deferred, pending_inval);
         } else {
             pkt->makeAtomicResponse();
-            pkt->setDataFromBlock(blk->data, blkSize);
+            // packets such as upgrades do not actually have any data
+            // payload
+            if (pkt->hasData())
+                pkt->setDataFromBlock(blk->data, blkSize);
         }
     }
 
index e2141a429318d852792213b571accf1cb8be1844..1d18a286132666856ed64a858eb5dc6c3fb8afa4 100644 (file)
@@ -115,6 +115,9 @@ MSHR::TargetList::add(PacketPtr pkt, Tick readyTime,
 static void
 replaceUpgrade(PacketPtr pkt)
 {
+    // remember if the current packet has data allocated
+    bool has_data = pkt->hasData() || pkt->hasRespData();
+
     if (pkt->cmd == MemCmd::UpgradeReq) {
         pkt->cmd = MemCmd::ReadExReq;
         DPRINTF(Cache, "Replacing UpgradeReq with ReadExReq\n");
@@ -125,6 +128,19 @@ replaceUpgrade(PacketPtr pkt)
         pkt->cmd = MemCmd::StoreCondFailReq;
         DPRINTF(Cache, "Replacing StoreCondReq with StoreCondFailReq\n");
     }
+
+    if (!has_data) {
+        // there is no sensible way of setting the data field if the
+        // new command actually would carry data
+        assert(!pkt->hasData());
+
+        if (pkt->hasRespData()) {
+            // we went from a packet that had no data (neither request,
+            // nor response), to one that does, and therefore we need to
+            // actually allocate space for the data payload
+            pkt->allocate();
+        }
+    }
 }
 
 
index 4614799bfa91fabe08bf8bba0d9b9978b7feb8bb..94508f697d8faafbcd2073c06df05696b95ef441 100644 (file)
@@ -508,6 +508,11 @@ class Packet : public Printable
     bool isEviction() const          { return cmd.isEviction(); }
     bool isWriteback() const         { return cmd.isWriteback(); }
     bool hasData() const             { return cmd.hasData(); }
+    bool hasRespData() const
+    {
+        MemCmd resp_cmd = cmd.responseCommand();
+        return resp_cmd.hasData();
+    }
     bool isLLSC() const              { return cmd.isLLSC(); }
     bool isError() const             { return cmd.isError(); }
     bool isPrint() const             { return cmd.isPrint(); }
@@ -1058,9 +1063,13 @@ class Packet : public Printable
     void
     allocate()
     {
-        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
-        flags.set(DYNAMIC_DATA);
-        data = new uint8_t[getSize()];
+        // if either this command or the response command has a data
+        // payload, actually allocate space
+        if (hasData() || hasRespData()) {
+            assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
+            flags.set(DYNAMIC_DATA);
+            data = new uint8_t[getSize()];
+        }
     }
 
     /** @} */