mem-ruby: MESI_Three_level prefetcher page crossing
authorTimothy Hayes <timothy.hayes@arm.com>
Tue, 21 Apr 2020 17:58:03 +0000 (18:58 +0100)
committerPouya Fotouhi <pfotouhi@ucdavis.edu>
Sat, 2 May 2020 06:50:57 +0000 (06:50 +0000)
This patch allows MESI_Three_level using the Ruby prefetcher to
safely cross page boundaries by determining if an address is bad
and cannot be mapped to a memory controller.

Change-Id: I675a13dfa6deb5b6a9f986ced5a3130436db911d
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28048
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
configs/ruby/MESI_Three_Level.py
src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm

index 0e9ef095effd633ff907250743ae4bd43078608d..61d6c523b6a19adf524ef2d479f752bf0e3b7773 100644 (file)
@@ -127,7 +127,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
                 nonunit_filter = 256,
                 train_misses = 5,
                 num_startup_pfs = 4,
-                cross_page = False
+                cross_page = True
             )
 
             l0_cntrl = L0Cache_Controller(
index da89bf5151dfccd3b482aead7a6f07824b69ea4c..3639ef2c594b60adbe84571de2e53b2160bfe74e 100644 (file)
@@ -140,6 +140,7 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache")
     PF_Load,         desc="Load request from prefetcher";
     PF_Ifetch,       desc="Instruction fetch request from prefetcher";
     PF_Store,        desc="Exclusive load request from prefetcher";
+    PF_Bad_Addr,     desc="Throw away prefetch request due to bad address generation";
   }
 
   // TYPES
@@ -323,7 +324,16 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache")
   in_port(optionalQueue_in, RubyRequest, prefetchQueue, desc="...", rank = 2) {
     if (optionalQueue_in.isReady(clockEdge())) {
       peek(optionalQueue_in, RubyRequest) {
-        if (in_msg.Type == RubyRequestType:IFETCH) {
+        // first check for valid address
+        MachineID mid := mapAddressToMachine(in_msg.LineAddress, MachineType:Directory);
+        NodeID nid := machineIDToNodeID(mid);
+        int nidint := IDToInt(nid);
+        int numDirs := machineCount(MachineType:Directory);
+        if (nidint >= numDirs) {
+          Entry cache_entry := static_cast(Entry, "pointer", Dcache.getNullEntry());
+          TBE tbe := TBEs.getNullEntry();
+          trigger(Event:PF_Bad_Addr, in_msg.LineAddress, cache_entry, tbe);
+        } else if (in_msg.Type == RubyRequestType:IFETCH) {
           // Instruction Prefetch
           Entry icache_entry := getICacheEntry(in_msg.LineAddress);
           if (is_valid(icache_entry)) {
@@ -1164,4 +1174,8 @@ machine(MachineType:L0Cache, "MESI Directory L0 Cache")
     o_popIncomingResponseQueue;
     kd_wakeUpDependents;
   }
+
+  transition(I, PF_Bad_Addr) {
+    pq_popPrefetchQueue;
+  }
 }