mem-cache: Promote deferred targets on cache clean responses
authorNikos Nikoleris <nikos.nikoleris@arm.com>
Sun, 18 Mar 2018 22:07:30 +0000 (22:07 +0000)
committerNikos Nikoleris <nikos.nikoleris@arm.com>
Fri, 22 Jun 2018 17:39:16 +0000 (17:39 +0000)
While a cache clean operation is pending, all requests to the
corresponding block get deferred. When the response of a cache clean
operation is received, if the block is present and the response is not
invalidating, we can service all deferred targets that didn't require
writable. This change implements this functionality.

Change-Id: Ief47e74d07749a6a9736ab450eb46eefa53464a2
Reviewed-on: https://gem5-review.googlesource.com/11018
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>

src/mem/cache/base.cc
src/mem/cache/cache.cc

index a510bac8ae11bba7025d37e4cebca2024a713766..8fd9ac2989ad37504cba6f8b64d786026cf99fb0 100644 (file)
@@ -491,6 +491,12 @@ BaseCache::recvTimingResp(PacketPtr pkt)
         // The block was marked not readable while there was a pending
         // cache maintenance operation, restore its flag.
         blk->status |= BlkReadable;
+
+        // This was a cache clean operation (without invalidate)
+        // and we have a copy of the block already. Since there
+        // is no invalidation, we can promote targets that don't
+        // require a writable copy
+        mshr->promoteReadable();
     }
 
     if (blk && blk->isWritable() && !pkt->req->isCacheInvalidate()) {
@@ -887,6 +893,8 @@ BaseCache::satisfyRequest(PacketPtr pkt, CacheBlk *blk, bool, bool)
             pkt->setCacheResponding();
             blk->status &= ~BlkDirty;
         }
+    } else if (pkt->isClean()) {
+        blk->status &= ~BlkDirty;
     } else {
         assert(pkt->isInvalidate());
         invalidateBlock(blk);
index ffd60811e4b1ecf00c89043e040d3259d630aefa..9b161290458313fc5182c2730b058d32f0fafc33 100644 (file)
@@ -674,8 +674,6 @@ Cache::serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk,
     const int initial_offset = initial_tgt->pkt->getOffset(blkSize);
 
     const bool is_error = pkt->isError();
-    bool is_fill = !mshr->isForward &&
-        (pkt->isRead() || pkt->cmd == MemCmd::UpgradeResp);
     // allow invalidation responses originating from write-line
     // requests to be discarded
     bool is_invalidate = pkt->isInvalidate();
@@ -716,13 +714,11 @@ Cache::serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk,
                                  targets.allocOnFill);
                 assert(blk);
 
-                // treat as a fill, and discard the invalidation
-                // response
-                is_fill = true;
+                // discard the invalidation response
                 is_invalidate = false;
             }
 
-            if (is_fill) {
+            if (blk && blk->isValid() && !mshr->isForward) {
                 satisfyRequest(tgt_pkt, blk, true, mshr->hasPostDowngrade());
 
                 // How many bytes past the first request is this one