Rahul Thakur has uploaded this change for review. ( https://gem5-review.googlesource.com/8681

Change subject: mem: Fix uncacheable write snoop flow
......................................................................

mem: Fix uncacheable write snoop flow

Earlier patches fixed handling of uncacheable IO WriteReq snoops hit in
caches by allowing in-place modification of cache block.

This patch proposes a few fixes in that:
1. Update upstream snoop packet with current snoop pkt data
2. Update mshr and cache block for WriteReq and additionally
   WriteLineReq which was previously left out.

Change-Id: Ia6fbdf53e92427f8e6ec74028b73769accc27562
---
M src/mem/cache/cache.cc
M src/mem/cache/mshr.cc
M src/mem/packet.hh
3 files changed, 49 insertions(+), 3 deletions(-)



diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc
index 1821f18..9cdc490 100644
--- a/src/mem/cache/cache.cc
+++ b/src/mem/cache/cache.cc
@@ -2069,6 +2069,15 @@
             // there is a snoop hit in upper levels
             Packet snoopPkt(pkt, true, true);
             snoopPkt.setExpressSnoop();
+
+            // Set data for the upstream snoop pkt from the current pkt
+            // which is write transaction and carries modified data
+            if ((pkt->cmd == MemCmd::WriteReq ||
+                 pkt->cmd == MemCmd::WriteLineReq) && !alreadyResponded) {
+                assert(pkt->req->isUncacheable());
+                snoopPkt.setData(pkt->getConstPtr<uint8_t>());
+            }
+
             // the snoop packet does not need to wait any additional
             // time
             snoopPkt.headerDelay = snoopPkt.payloadDelay = 0;
@@ -2211,6 +2220,18 @@
             // we already called setHasSharers above
         }

+        // For uncacheable write, update the dirty data
+ if (pkt->cmd == MemCmd::WriteReq || pkt->cmd == MemCmd::WriteLineReq) {
+            assert(pkt->req->isUncacheable());
+            // write the partial line to the right part of the block
+            pkt->writeDataToBlock(blk->data, blkSize);
+
+            // the block is not going to end up with a cache
+            // allocation, but set the flag to indicate that there are
+            // sharers, also to avoid the panic below
+            pkt->setHasSharers();
+        }
+
         // if we are returning a writable and dirty (Modified) line,
         // we should be invalidating the line
         panic_if(!invalidate && !pkt->hasSharers(),
@@ -2356,6 +2377,19 @@
                 pkt->setResponderHadWritable();
             }

+            // partial line uncacheable write, update the dirty data
+            if (pkt->cmd == MemCmd::WriteReq ||
+                pkt->cmd == MemCmd::WriteLineReq) {
+                assert(pkt->req->isUncacheable());
+                // write the partial line to the right part of the
+                // writeback packet
+                pkt->writeDataToBlock(wb_pkt->getPtr<uint8_t>(), blkSize);
+
+                // not strictly necessary, but set the flag indicating
+                // that the packet has sharers
+                pkt->setHasSharers();
+            }
+
             doTimingSupplyResponse(pkt, wb_pkt->getConstPtr<uint8_t>(),
                                    false, false);
         }
diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc
index 493b7f0..5af4f6a 100644
--- a/src/mem/cache/mshr.cc
+++ b/src/mem/cache/mshr.cc
@@ -425,8 +425,19 @@
         // the latter case the cache is responsible for deleting both
         // the packet and the request as part of handling the deferred
         // snoop.
-        PacketPtr cp_pkt = will_respond ? new Packet(pkt, true, true) :
-            new Packet(new Request(*pkt->req), pkt->cmd, blkSize, pkt->id);
+        PacketPtr cp_pkt = nullptr;
+        if (will_respond) {
+            cp_pkt = new Packet(pkt, true, true);
+            //  Update the data if request is write carrying updated data
+            if (pkt->cmd == MemCmd::WriteReq ||
+                pkt->cmd == MemCmd::WriteLineReq) {
+                assert(pkt->req->isUncacheable());
+                cp_pkt->allocate();
+                cp_pkt->setData(pkt->getConstPtr<uint8_t>());
+            }
+        } else {
+            cp_pkt = new Packet(new Request(*pkt->req), pkt->cmd, blkSize);
+        }

         if (will_respond) {
             // we are the ordering point, and will consequently
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index 66625b3..1f481db 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -530,7 +530,8 @@
         // look at the hasSharers flag (if not set, the response is to
         // be considered writable)
         assert(isRequest());
-        return cmd.needsWritable();
+        // ignore the needsWritable flag if the packet is uncacheable
+        return cmd.needsWritable() && !req->isUncacheable();
     }
     bool needsResponse() const       { return cmd.needsResponse(); }
     bool isInvalidate() const        { return cmd.isInvalidate(); }

--
To view, visit https://gem5-review.googlesource.com/8681
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: Ia6fbdf53e92427f8e6ec74028b73769accc27562
Gerrit-Change-Number: 8681
Gerrit-PatchSet: 1
Gerrit-Owner: Rahul Thakur <rjtha...@google.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to