Hello Timothy Hayes,
I'd like you to do a code review. Please visit
https://gem5-review.googlesource.com/c/public/gem5/+/28328
to review the following change.
Change subject: mem-ruby: MESI_Three_Level LL/SC improvements
......................................................................
mem-ruby: MESI_Three_Level LL/SC improvements
This patch fixes the MESI_Three_Level protocols so that it correctly
informers the Ruby sequencer when a line eviction occurs. Furthermore,
the patch allows the protocol to recognize the 'Store_Conditional'
RubyRequestType and shortcuts this operation if the monitored line
has been cleared from the address monitor. This prevents certain
livelock behaviour in which a line could ping-pong between competing
cores.
The patch establishes a new C/C++ preprocessor definition which allows
the Sequencer to send the 'Store_Conditional' RubyRequestType to
MESI_Three_Level instead of 'ST'. This is a temporary measure until
the other protocols explicitely recognize 'Store_Conditional'.
Change-Id: I27ae041ab0e015a4f54f20df666f9c4873c7583d
---
M src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm
M src/mem/ruby/system/SConscript
M src/mem/ruby/system/Sequencer.cc
3 files changed, 77 insertions(+), 23 deletions(-)
diff --git a/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm
b/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm
index b74a727..14fb07a 100644
--- a/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm
+++ b/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm
@@ -121,6 +121,8 @@
Ack, desc="Ack for processor";
WB_Ack, desc="Ack for replacement";
+
+ Failed_SC, desc="Store conditional request that will fail";
}
// TYPES
@@ -257,7 +259,8 @@
return Event:Load;
} else if (type == RubyRequestType:IFETCH) {
return Event:Ifetch;
- } else if ((type == RubyRequestType:ST) || (type ==
RubyRequestType:ATOMIC)) {
+ } else if ((type == RubyRequestType:ST) || (type ==
RubyRequestType:ATOMIC)
+ || (type == RubyRequestType:Store_Conditional)) {
return Event:Store;
} else {
error("Invalid RubyRequestType");
@@ -349,36 +352,51 @@
}
}
} else {
-
// *** DATA ACCESS ***
Entry Dcache_entry := getDCacheEntry(in_msg.LineAddress);
+
+ // early out for failed store conditionals
+
+ if (in_msg.Type == RubyRequestType:Store_Conditional) {
+ if (!sequencer.llscCheckMonitor(in_msg.LineAddress)) {
+ trigger(Event:Failed_SC, in_msg.LineAddress,
+ Dcache_entry, TBEs[in_msg.LineAddress]);
+ }
+ }
+
if (is_valid(Dcache_entry)) {
// The tag matches for the L0, so the L0 ask the L1 for it
trigger(mandatory_request_type_to_event(in_msg.Type),
in_msg.LineAddress,
Dcache_entry, TBEs[in_msg.LineAddress]);
} else {
-
- // Check to see if it is in the OTHER L0
- Entry Icache_entry := getICacheEntry(in_msg.LineAddress);
- if (is_valid(Icache_entry)) {
- // The block is in the wrong L0, put the request on the
queue to the private L1
- trigger(Event:L0_Replacement, in_msg.LineAddress,
- Icache_entry, TBEs[in_msg.LineAddress]);
- }
-
- if (Dcache.cacheAvail(in_msg.LineAddress)) {
- // L1 does't have the line, but we have space for it
- // in the L0 let's see if the L1 has it
- trigger(mandatory_request_type_to_event(in_msg.Type),
in_msg.LineAddress,
- Dcache_entry, TBEs[in_msg.LineAddress]);
+ // if the request is not valid, the store conditional will fail
+ if (in_msg.Type == RubyRequestType:Store_Conditional) {
+ // if the line is not valid, it can't be locked
+ trigger(Event:Failed_SC, in_msg.LineAddress,
+ Dcache_entry, TBEs[in_msg.LineAddress]);
} else {
- // No room in the L1, so we need to make room in the L0
- // Check if the line we want to evict is not locked
- Addr addr := Dcache.cacheProbe(in_msg.LineAddress);
- check_on_cache_probe(mandatoryQueue_in, addr);
- trigger(Event:L0_Replacement, addr,
- getDCacheEntry(addr),
- TBEs[addr]);
+ // Check to see if it is in the OTHER L0
+ Entry Icache_entry := getICacheEntry(in_msg.LineAddress);
+ if (is_valid(Icache_entry)) {
+ // The block is in the wrong L0, put the request on the
queue to the private L1
+ trigger(Event:L0_Replacement, in_msg.LineAddress,
+ Icache_entry, TBEs[in_msg.LineAddress]);
+ }
+
+ if (Dcache.cacheAvail(in_msg.LineAddress)) {
+ // L1 does't have the line, but we have space for it
+ // in the L0 let's see if the L1 has it
+ trigger(mandatory_request_type_to_event(in_msg.Type),
in_msg.LineAddress,
+ Dcache_entry, TBEs[in_msg.LineAddress]);
+ } else {
+ // No room in the L1, so we need to make room in the L0
+ // Check if the line we want to evict is not locked
+ Addr addr := Dcache.cacheProbe(in_msg.LineAddress);
+ check_on_cache_probe(mandatoryQueue_in, addr);
+ trigger(Event:L0_Replacement, addr,
+ getDCacheEntry(addr),
+ TBEs[addr]);
+ }
}
}
}
@@ -629,6 +647,13 @@
++Dcache.demand_hits;
}
+ // store conditionals
+
+ action(hhc_storec_fail, "\hc",
+ desc="Notify sequencer that store conditional failed") {
+ sequencer.writeCallbackScFail(address, cache_entry.DataBlk);
+ }
+
//*****************************************************
// TRANSITIONS
//*****************************************************
@@ -664,11 +689,13 @@
}
transition({I, IS, IM, Inst_IS}, {InvOwn, InvElse}) {
+ forward_eviction_to_cpu;
fi_sendInvAck;
l_popRequestQueue;
}
transition(SM, {InvOwn, InvElse}, IM) {
+ forward_eviction_to_cpu;
fi_sendInvAck;
l_popRequestQueue;
}
@@ -768,6 +795,7 @@
transition(IS, Data_Stale, I) {
u_writeDataToCache;
+ forward_eviction_to_cpu;
hx_load_hit;
s_deallocateTBE;
ff_deallocateCacheBlock;
@@ -807,4 +835,12 @@
o_popIncomingResponseQueue;
kd_wakeUpDependents;
}
+
+ // store conditionals
+
+ transition({I,S,E,M}, Failed_SC) {
+ // IS,IM,SM don't handle store conditionals
+ hhc_storec_fail;
+ k_popMandatoryQueue;
+ }
}
diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript
index d196b68..7496971 100644
--- a/src/mem/ruby/system/SConscript
+++ b/src/mem/ruby/system/SConscript
@@ -1,5 +1,17 @@
# -*- mode:python -*-
+# Copyright (c) 2020 ARM Limited
+# All rights reserved.
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder. You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
@@ -31,6 +43,8 @@
if env['PROTOCOL'] == 'None':
Return()
+env.Append(CPPDEFINES=['PROTOCOL_' + env['PROTOCOL']])
+
if env['BUILD_GPU']:
SimObject('GPUCoalescer.py')
SimObject('RubySystem.py')
diff --git a/src/mem/ruby/system/Sequencer.cc
b/src/mem/ruby/system/Sequencer.cc
index 0287e13..de7941a 100644
--- a/src/mem/ruby/system/Sequencer.cc
+++ b/src/mem/ruby/system/Sequencer.cc
@@ -590,7 +590,11 @@
if (pkt->isWrite()) {
DPRINTF(RubySequencer, "Issuing SC\n");
primary_type = RubyRequestType_Store_Conditional;
+#ifdef PROTOCOL_MESI_Three_Level
+ secondary_type = RubyRequestType_Store_Conditional;
+#else
secondary_type = RubyRequestType_ST;
+#endif
} else {
DPRINTF(RubySequencer, "Issuing LL\n");
assert(pkt->isRead());
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/28328
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I27ae041ab0e015a4f54f20df666f9c4873c7583d
Gerrit-Change-Number: 28328
Gerrit-PatchSet: 1
Gerrit-Owner: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-Reviewer: Timothy Hayes <timothy.ha...@arm.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s