mem: Always use InvalidateReq to service WriteLineReq misses
authorNikos Nikoleris <nikos.nikoleris@arm.com>
Mon, 5 Dec 2016 21:48:25 +0000 (16:48 -0500)
committerNikos Nikoleris <nikos.nikoleris@arm.com>
Mon, 5 Dec 2016 21:48:25 +0000 (16:48 -0500)
Previously, a WriteLineReq that missed in a cache would send out an
InvalidateReq if the block lookup failed or an UpgradeReq if the
block lookup succeeded but the block had sharers. This changes ensures
that a WriteLineReq always sends an InvalidateReq to invalidate all
copies of the block and satisfy the WriteLineReq.

Change-Id: I207ff5b267663abf02bc0b08aeadde69ad81be61
Reviewed-by: Andreas Hansson <andreas.hansson@arm.com>
src/mem/cache/cache.cc

index 6f02edb8268f17f6cc50165792c3e235247d7df3..48382814f8d6e7e687c3df2cf73bafc7b8f2a5ac 100644 (file)
@@ -924,7 +924,13 @@ Cache::createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk,
     // write miss on a shared owned block will generate a ReadExcl,
     // which will clobber the owned copy.
     const bool useUpgrades = true;
-    if (blkValid && useUpgrades) {
+    if (cpu_pkt->cmd == MemCmd::WriteLineReq) {
+        assert(!blkValid || !blk->isWritable());
+        // forward as invalidate to all other caches, this gives us
+        // the line in Exclusive state, and invalidates all other
+        // copies
+        cmd = MemCmd::InvalidateReq;
+    } else if (blkValid && useUpgrades) {
         // only reason to be here is that blk is read only and we need
         // it to be writable
         assert(needsWritable);
@@ -937,11 +943,6 @@ Cache::createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk,
         // where the determination the StoreCond fails is delayed due to
         // all caches not being on the same local bus.
         cmd = MemCmd::SCUpgradeFailReq;
-    } else if (cpu_pkt->cmd == MemCmd::WriteLineReq) {
-        // forward as invalidate to all other caches, this gives us
-        // the line in Exclusive state, and invalidates all other
-        // copies
-        cmd = MemCmd::InvalidateReq;
     } else {
         // block is invalid
         cmd = needsWritable ? MemCmd::ReadExReq :