From c31bc284a8bae4d7e235bae11a12f0460ce2b2b7 Mon Sep 17 00:00:00 2001 From: Marleson Graf <9793033+hexengraf@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:47:45 -0300 Subject: [PATCH] mem-ruby,sim-se: Fix functional reads for MESI protocols This commit fixes three issues in MESI_Three_Level and MESI_Two_Level implementations (MEI_Three_Level_HTM might still have issues). 1) Define functional read priorities for the cache controllers which have states with Maybe_Stale access permission (L1 > L2 > Directory). 2) Fix incorrect access permissions in MESI_Three_Level-L1cache: * S_IL0 is Read_Only, it is waiting for L0 to acknowledge the invalidation request before moving to SS, also a Read_Only state. * E_IL0 is Maybe_Stale, its contents might be valid, since there is a transition (E_IL0, L0_Ack, EE) with no writeback data. * M_IL0 is Maybe_Stale, its contents might be valid, since there is a transition (M_IL0, L0_Ack, MM) with no writeback data. 3) Add missing message types carrying valid data in functional reads: * INV_DATA is a writeback from L0 to L1. * DATA is a response to GET_S, but there are scenarios where it might be the only place with valid data (e.g. during L2 replacement). Change-Id: Ie44fa317027f9ede272967e7461d337e14355eec --- src/mem/ruby/protocol/MESI_Three_Level-L1cache.sm | 10 +++++++--- src/mem/ruby/protocol/MESI_Three_Level-msg.sm | 2 ++ src/mem/ruby/protocol/MESI_Two_Level-L2cache.sm | 4 ++++ src/mem/ruby/protocol/MESI_Two_Level-dir.sm | 4 ++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/mem/ruby/protocol/MESI_Three_Level-L1cache.sm b/src/mem/ruby/protocol/MESI_Three_Level-L1cache.sm index ed5e40cfa1..c7a1ae585a 100644 --- a/src/mem/ruby/protocol/MESI_Three_Level-L1cache.sm +++ b/src/mem/ruby/protocol/MESI_Three_Level-L1cache.sm @@ -90,9 +90,9 @@ machine(MachineType:L1Cache, "MESI Directory L1 Cache CMP") // For all of the following states, invalidate // message has been sent to L0 cache. The response // from the L0 cache has not been seen yet. - S_IL0, AccessPermission:Busy, desc="Shared in L1, invalidation sent to L0, have not seen response yet"; - E_IL0, AccessPermission:Busy, desc="Exclusive in L1, invalidation sent to L0, have not seen response yet"; - M_IL0, AccessPermission:Busy, desc="Modified in L1, invalidation sent to L0, have not seen response yet"; + S_IL0, AccessPermission:Read_Only, desc="Shared in L1, invalidation sent to L0, have not seen response yet"; + E_IL0, AccessPermission:Maybe_Stale, desc="Exclusive in L1, invalidation sent to L0, have not seen response yet"; + M_IL0, AccessPermission:Maybe_Stale, desc="Modified in L1, invalidation sent to L0, have not seen response yet"; MM_IL0, AccessPermission:Read_Write, desc="Invalidation sent to L0, have not seen response yet"; SM_IL0, AccessPermission:Busy, desc="Invalidation sent to L0, have not seen response yet"; } @@ -231,6 +231,10 @@ machine(MachineType:L1Cache, "MESI Directory L1 Cache CMP") } } + int functionalReadPriority() { + return 10; + } + int functionalWrite(Addr addr, Packet *pkt) { int num_functional_writes := 0; diff --git a/src/mem/ruby/protocol/MESI_Three_Level-msg.sm b/src/mem/ruby/protocol/MESI_Three_Level-msg.sm index 740011ac83..fe855f8e22 100644 --- a/src/mem/ruby/protocol/MESI_Three_Level-msg.sm +++ b/src/mem/ruby/protocol/MESI_Three_Level-msg.sm @@ -83,6 +83,8 @@ structure(CoherenceMsg, desc="...", interface="Message") { bool functionalRead(Packet *pkt) { // Valid data block is only present in message with following types if (Class == CoherenceClass:PUTX || + Class == CoherenceClass:INV_DATA || + Class == CoherenceClass:DATA || Class == CoherenceClass:DATA_EXCLUSIVE) { return testAndRead(addr, DataBlk, pkt); } diff --git a/src/mem/ruby/protocol/MESI_Two_Level-L2cache.sm b/src/mem/ruby/protocol/MESI_Two_Level-L2cache.sm index b189f71cab..1562db17e9 100644 --- a/src/mem/ruby/protocol/MESI_Two_Level-L2cache.sm +++ b/src/mem/ruby/protocol/MESI_Two_Level-L2cache.sm @@ -238,6 +238,10 @@ machine(MachineType:L2Cache, "MESI Directory L2 Cache CMP") } } + int functionalReadPriority() { + return 20; + } + int functionalWrite(Addr addr, Packet *pkt) { int num_functional_writes := 0; diff --git a/src/mem/ruby/protocol/MESI_Two_Level-dir.sm b/src/mem/ruby/protocol/MESI_Two_Level-dir.sm index 84ec578788..0b9a66547a 100644 --- a/src/mem/ruby/protocol/MESI_Two_Level-dir.sm +++ b/src/mem/ruby/protocol/MESI_Two_Level-dir.sm @@ -163,6 +163,10 @@ machine(MachineType:Directory, "MESI Two Level directory protocol") } } + int functionalReadPriority() { + return 30; + } + int functionalWrite(Addr addr, Packet *pkt) { int num_functional_writes := 0;