changeset 279efb97ec99 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=279efb97ec99
description:
        mem: Remove redundant is_top_level cache parameter

        This patch takes the final step in removing the is_top_level parameter
        from the cache. With the recent changes to read requests and write
        invalidations, the parameter is no longer needed, and consequently
        removed.

        This also means that asymmetric cache hierarchies are now fully
        supported (and we are actually using them already with L1 caches, but
        no table-walker caches, connected to a shared L2).

diffstat:

 configs/common/Caches.py     |   3 ---
 configs/common/O3_ARM_v7a.py |   3 ---
 configs/example/memcheck.py  |   3 +--
 configs/example/memtest.py   |   3 +--
 src/mem/cache/BaseCache.py   |   1 -
 src/mem/cache/base.cc        |   1 -
 src/mem/cache/base.hh        |   5 -----
 src/mem/cache/cache_impl.hh  |  25 +++++++++++++------------
 8 files changed, 15 insertions(+), 29 deletions(-)

diffs (221 lines):

diff -r fdd4a895f325 -r 279efb97ec99 configs/common/Caches.py
--- a/configs/common/Caches.py  Fri Jul 03 10:14:41 2015 -0400
+++ b/configs/common/Caches.py  Fri Jul 03 10:14:43 2015 -0400
@@ -52,7 +52,6 @@
     response_latency = 2
     mshrs = 4
     tgts_per_mshr = 20
-    is_top_level = True
 
 class L1_ICache(L1Cache):
     is_read_only = True
@@ -76,7 +75,6 @@
     size = '1kB'
     tgts_per_mshr = 12
     forward_snoops = False
-    is_top_level = True
 
 class PageTableWalkerCache(BaseCache):
     assoc = 2
@@ -86,7 +84,6 @@
     size = '1kB'
     tgts_per_mshr = 12
     forward_snoops = False
-    is_top_level = True
     # the x86 table walker actually writes to the table-walker cache
     if buildEnv['TARGET_ISA'] == 'x86':
         is_read_only = False
diff -r fdd4a895f325 -r 279efb97ec99 configs/common/O3_ARM_v7a.py
--- a/configs/common/O3_ARM_v7a.py      Fri Jul 03 10:14:41 2015 -0400
+++ b/configs/common/O3_ARM_v7a.py      Fri Jul 03 10:14:43 2015 -0400
@@ -149,7 +149,6 @@
     tgts_per_mshr = 8
     size = '32kB'
     assoc = 2
-    is_top_level = True
     forward_snoops = False
     is_read_only = True
 
@@ -162,7 +161,6 @@
     size = '32kB'
     assoc = 2
     write_buffers = 16
-    is_top_level = True
 
 # TLB Cache
 # Use a cache as a L2 TLB
@@ -174,7 +172,6 @@
     size = '1kB'
     assoc = 8
     write_buffers = 16
-    is_top_level = True
     forward_snoops = False
     is_read_only = True
 
diff -r fdd4a895f325 -r 279efb97ec99 configs/example/memcheck.py
--- a/configs/example/memcheck.py       Fri Jul 03 10:14:41 2015 -0400
+++ b/configs/example/memcheck.py       Fri Jul 03 10:14:43 2015 -0400
@@ -154,7 +154,7 @@
 # Define a prototype L1 cache that we scale for all successive levels
 proto_l1 = BaseCache(size = '32kB', assoc = 4,
                      hit_latency = 1, response_latency = 1,
-                     tgts_per_mshr = 8, is_top_level = True)
+                     tgts_per_mshr = 8)
 
 if options.blocking:
      proto_l1.mshrs = 1
@@ -179,7 +179,6 @@
      next.response_latency = prev.response_latency * 10
      next.assoc = prev.assoc * scale
      next.mshrs = prev.mshrs * scale
-     next.is_top_level = False
      cache_proto.insert(0, next)
 
 # Create a config to be used by all the traffic generators
diff -r fdd4a895f325 -r 279efb97ec99 configs/example/memtest.py
--- a/configs/example/memtest.py        Fri Jul 03 10:14:41 2015 -0400
+++ b/configs/example/memtest.py        Fri Jul 03 10:14:43 2015 -0400
@@ -177,7 +177,7 @@
 # Define a prototype L1 cache that we scale for all successive levels
 proto_l1 = BaseCache(size = '32kB', assoc = 4,
                      hit_latency = 1, response_latency = 1,
-                     tgts_per_mshr = 8, is_top_level = True)
+                     tgts_per_mshr = 8)
 
 if options.blocking:
      proto_l1.mshrs = 1
@@ -197,7 +197,6 @@
      next.response_latency = prev.response_latency * 10
      next.assoc = prev.assoc * scale
      next.mshrs = prev.mshrs * scale
-     next.is_top_level = False
      cache_proto.insert(0, next)
 
 # Make a prototype for the tester to be used throughout
diff -r fdd4a895f325 -r 279efb97ec99 src/mem/cache/BaseCache.py
--- a/src/mem/cache/BaseCache.py        Fri Jul 03 10:14:41 2015 -0400
+++ b/src/mem/cache/BaseCache.py        Fri Jul 03 10:14:43 2015 -0400
@@ -64,7 +64,6 @@
 
     forward_snoops = Param.Bool(True,
         "Forward snoops from mem side to cpu side")
-    is_top_level = Param.Bool(False, "Is this cache at the top level (e.g. 
L1)")
     is_read_only = Param.Bool(False, "Is this cache read only (e.g. inst)")
 
     prefetcher = Param.BasePrefetcher(NULL,"Prefetcher attached to cache")
diff -r fdd4a895f325 -r 279efb97ec99 src/mem/cache/base.cc
--- a/src/mem/cache/base.cc     Fri Jul 03 10:14:41 2015 -0400
+++ b/src/mem/cache/base.cc     Fri Jul 03 10:14:43 2015 -0400
@@ -78,7 +78,6 @@
       responseLatency(p->response_latency),
       numTarget(p->tgts_per_mshr),
       forwardSnoops(p->forward_snoops),
-      isTopLevel(p->is_top_level),
       isReadOnly(p->is_read_only),
       blocked(0),
       order(0),
diff -r fdd4a895f325 -r 279efb97ec99 src/mem/cache/base.hh
--- a/src/mem/cache/base.hh     Fri Jul 03 10:14:41 2015 -0400
+++ b/src/mem/cache/base.hh     Fri Jul 03 10:14:43 2015 -0400
@@ -304,11 +304,6 @@
     /** Do we forward snoops from mem side port through to cpu side port? */
     const bool forwardSnoops;
 
-    /** Is this cache a toplevel cache (e.g. L1, I/O cache). If so we should
-     * never try to forward ownership and similar optimizations to the cpu
-     * side */
-    const bool isTopLevel;
-
     /**
      * Is this cache read only, for example the instruction cache, or
      * table-walker cache. A cache that is read only should never see
diff -r fdd4a895f325 -r 279efb97ec99 src/mem/cache/cache_impl.hh
--- a/src/mem/cache/cache_impl.hh       Fri Jul 03 10:14:41 2015 -0400
+++ b/src/mem/cache/cache_impl.hh       Fri Jul 03 10:14:43 2015 -0400
@@ -179,7 +179,15 @@
             blk->trackLoadLocked(pkt);
         }
         pkt->setDataFromBlock(blk->data, blkSize);
-        if (pkt->getSize() == 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
+        // bit cleaner
+        if (pkt->cmd == MemCmd::ReadExReq ||
+            pkt->cmd == MemCmd::ReadSharedReq ||
+            pkt->cmd == MemCmd::ReadCleanReq ||
+            pkt->cmd == MemCmd::SCUpgradeFailReq) {
+            assert(pkt->getSize() == blkSize);
             // special handling for coherent block requests from
             // upper-level caches
             if (pkt->needsExclusive()) {
@@ -211,7 +219,7 @@
 
                 if (blk->isDirty()) {
                     // special considerations if we're owner:
-                    if (!deferred_response && !isTopLevel) {
+                    if (!deferred_response) {
                         // if we are responding immediately and can
                         // signal that we're transferring ownership
                         // along with exclusivity, do so
@@ -526,7 +534,6 @@
         (pkt->getSize() == blkSize) && (pkt->getOffset(blkSize) == 0)) {
         pkt->cmd = MemCmd::WriteLineReq;
         DPRINTF(Cache, "packet promoted from Write to WriteLineReq\n");
-        assert(isTopLevel); // should only happen at L1 or I/O cache
     }
 }
 
@@ -696,7 +703,7 @@
         // processing happens before any MSHR munging on the behalf of
         // this request because this new Request will be the one stored
         // into the MSHRs, not the original.
-        if (pkt->cmd.isSWPrefetch() && isTopLevel) {
+        if (pkt->cmd.isSWPrefetch()) {
             assert(needsResponse);
             assert(pkt->req->hasPaddr());
             assert(!pkt->req->isUncacheable());
@@ -905,7 +912,6 @@
         // the line in exclusive state, and invalidates all other
         // copies
         cmd = MemCmd::InvalidateReq;
-        assert(isTopLevel);
     } else {
         // block is invalid
         cmd = needsExclusive ? MemCmd::ReadExReq :
@@ -1034,17 +1040,12 @@
                     pkt->makeAtomicResponse();
                     pkt->copyError(bus_pkt);
                 } else if (pkt->cmd == MemCmd::InvalidateReq) {
-                    assert(!isTopLevel);
                     if (blk) {
                         // invalidate response to a cache that received
                         // an invalidate request
                         satisfyCpuSideRequest(pkt, blk);
                     }
                 } else if (pkt->cmd == MemCmd::WriteLineReq) {
-                    // invalidate response to the cache that
-                    // received the original write-line request
-                    assert(isTopLevel);
-
                     // note the use of pkt, not bus_pkt here.
 
                     // write-line request to the cache that promoted
@@ -1256,7 +1257,7 @@
             completion_time = pkt->headerDelay;
 
             // Software prefetch handling for cache closest to core
-            if (tgt_pkt->cmd.isSWPrefetch() && isTopLevel) {
+            if (tgt_pkt->cmd.isSWPrefetch()) {
                 // a software prefetch would have already been ack'd 
immediately
                 // with dummy data so the core would be able to retire it.
                 // this request completes right here, so we deallocate it.
@@ -2148,7 +2149,7 @@
 bool
 Cache::isCachedAbove(const PacketPtr pkt) const
 {
-    if (isTopLevel)
+    if (!forwardSnoops)
         return false;
     // Mirroring the flow of HardPFReqs, the cache sends CleanEvict and
     // Writeback snoops into upper level caches to check for copies of the
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to