[gem5-dev] Change in gem5/gem5[develop]: mem-ruby: LL/SC fixes

2020-05-02 Thread Pouya Fotouhi (Gerrit) via gem5-dev
Pouya Fotouhi has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/27103 )


Change subject: mem-ruby: LL/SC fixes
..

mem-ruby: LL/SC fixes

The implementation for load-linked/store-conditional did not work
correctly for multi-core simulations. Since load-links were treated as
stores, it was not possible for a line to have multiple readers which
often resulted in livelock when using these instructions to implemented
mutexes. This improved implementation treats load-linked instructions
similarly to loads but locks the line after a copy has been fetched
locally. Writes to a monitored address ensure the 'linked' property is
blown away and any subsequent store-conditional will fail.

Change-Id: I19bd74459e26732c92c8b594901936e6439fb073
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27103
Reviewed-by: Daniel Carvalho 
Maintainer: Bobby R. Bruce 
Tested-by: kokoro 
---
M src/mem/ruby/protocol/RubySlicc_Types.sm
M src/mem/ruby/system/Sequencer.cc
M src/mem/ruby/system/Sequencer.hh
3 files changed, 155 insertions(+), 73 deletions(-)

Approvals:
  Daniel Carvalho: Looks good to me, approved
  Bobby R. Bruce: Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/mem/ruby/protocol/RubySlicc_Types.sm  
b/src/mem/ruby/protocol/RubySlicc_Types.sm

index fd76289..f8de9ed 100644
--- a/src/mem/ruby/protocol/RubySlicc_Types.sm
+++ b/src/mem/ruby/protocol/RubySlicc_Types.sm
@@ -1,4 +1,16 @@
 /*
+ * 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) 1999-2005 Mark D. Hill and David A. Wood
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
@@ -112,6 +124,10 @@
   void writeCallback(Addr, DataBlock, bool, MachineType,
  Cycles, Cycles, Cycles);

+  // ll/sc support
+  void writeCallbackScFail(Addr, DataBlock);
+  bool llscCheckMonitor(Addr);
+
   void checkCoherence(Addr);
   void evictionCallback(Addr);
   void recordRequestType(SequencerRequestType);
diff --git a/src/mem/ruby/system/Sequencer.cc  
b/src/mem/ruby/system/Sequencer.cc

index 1f538c3..0287e13 100644
--- a/src/mem/ruby/system/Sequencer.cc
+++ b/src/mem/ruby/system/Sequencer.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 ARM Limited
+ * Copyright (c) 2019-2020 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -45,6 +45,7 @@
 #include "base/logging.hh"
 #include "base/str.hh"
 #include "cpu/testers/rubytest/RubyTester.hh"
+#include "debug/LLSC.hh"
 #include "debug/MemoryAccess.hh"
 #include "debug/ProtocolTrace.hh"
 #include "debug/RubySequencer.hh"
@@ -90,6 +91,64 @@
 }

 void
+Sequencer::llscLoadLinked(const Addr claddr)
+{
+AbstractCacheEntry *line = m_dataCache_ptr->lookup(claddr);
+if (line) {
+line->setLocked(m_version);
+DPRINTF(LLSC, "LLSC Monitor - inserting load linked - "
+  "addr=0x%lx - cpu=%u\n", claddr, m_version);
+}
+}
+
+void
+Sequencer::llscClearMonitor(const Addr claddr)
+{
+AbstractCacheEntry *line = m_dataCache_ptr->lookup(claddr);
+if (line && line->isLocked(m_version)) {
+line->clearLocked();
+DPRINTF(LLSC, "LLSC Monitor - clearing due to store - "
+  "addr=0x%lx - cpu=%u\n", claddr, m_version);
+}
+}
+
+bool
+Sequencer::llscStoreConditional(const Addr claddr)
+{
+AbstractCacheEntry *line = m_dataCache_ptr->lookup(claddr);
+if (!line)
+return false;
+
+DPRINTF(LLSC, "LLSC Monitor - clearing due to "
+  "store conditional - "
+  "addr=0x%lx - cpu=%u\n",
+  claddr, m_version);
+
+if (line->isLocked(m_version)) {
+line->clearLocked();
+return true;
+} else {
+line->clearLocked();
+return false;
+}
+}
+
+bool
+Sequencer::llscCheckMonitor(const Addr address)
+{
+const Addr claddr = makeLineAddress(address);
+AbstractCacheEntry *line = m_dataCache_ptr->lookup(claddr);
+if (!line)
+return false;
+
+if (line->isLocked(m_version)) {
+return true;
+} else {
+return false;
+}
+}
+
+void
 Sequencer::wakeup()
 {
 assert(drainState() != DrainState::Draining);
@@ -203,62 +262,6 @@
 }

 void
-Sequencer::invalidateSC(Addr address)
-{
-AbstractCacheEntry *e = 

[gem5-dev] Change in gem5/gem5[develop]: mem-ruby: LL/SC fixes

2020-04-30 Thread Giacomo Travaglini (Gerrit) via gem5-dev

Hello Timothy Hayes,

I'd like you to do a code review. Please visit

https://gem5-review.googlesource.com/c/public/gem5/+/28327

to review the following change.


Change subject: mem-ruby: LL/SC fixes
..

mem-ruby: LL/SC fixes

The implementation for load-linked/store-conditional did not work
correctly for multi-core simulations. Since load-links were treated as
stores, it was not possible for a line to have multiple readers which
often resulted in livelock when using these instructions to implemented
mutexes. This improved implementation treats load-linked instructions
similarly to loads but locks the line after a copy has been fetched
locally. Writes to a monitored address ensure the 'linked' property is
blown away and any subsequent store-conditional will fail.

Change-Id: I3c8b29b66b8200de23cb141bf25bee710d79f844
---
M src/mem/ruby/protocol/RubySlicc_Types.sm
M src/mem/ruby/system/Sequencer.cc
M src/mem/ruby/system/Sequencer.hh
3 files changed, 155 insertions(+), 73 deletions(-)



diff --git a/src/mem/ruby/protocol/RubySlicc_Types.sm  
b/src/mem/ruby/protocol/RubySlicc_Types.sm

index fd76289..f8de9ed 100644
--- a/src/mem/ruby/protocol/RubySlicc_Types.sm
+++ b/src/mem/ruby/protocol/RubySlicc_Types.sm
@@ -1,4 +1,16 @@
 /*
+ * 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) 1999-2005 Mark D. Hill and David A. Wood
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
@@ -112,6 +124,10 @@
   void writeCallback(Addr, DataBlock, bool, MachineType,
  Cycles, Cycles, Cycles);

+  // ll/sc support
+  void writeCallbackScFail(Addr, DataBlock);
+  bool llscCheckMonitor(Addr);
+
   void checkCoherence(Addr);
   void evictionCallback(Addr);
   void recordRequestType(SequencerRequestType);
diff --git a/src/mem/ruby/system/Sequencer.cc  
b/src/mem/ruby/system/Sequencer.cc

index 1f538c3..0287e13 100644
--- a/src/mem/ruby/system/Sequencer.cc
+++ b/src/mem/ruby/system/Sequencer.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 ARM Limited
+ * Copyright (c) 2019-2020 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -45,6 +45,7 @@
 #include "base/logging.hh"
 #include "base/str.hh"
 #include "cpu/testers/rubytest/RubyTester.hh"
+#include "debug/LLSC.hh"
 #include "debug/MemoryAccess.hh"
 #include "debug/ProtocolTrace.hh"
 #include "debug/RubySequencer.hh"
@@ -90,6 +91,64 @@
 }

 void
+Sequencer::llscLoadLinked(const Addr claddr)
+{
+AbstractCacheEntry *line = m_dataCache_ptr->lookup(claddr);
+if (line) {
+line->setLocked(m_version);
+DPRINTF(LLSC, "LLSC Monitor - inserting load linked - "
+  "addr=0x%lx - cpu=%u\n", claddr, m_version);
+}
+}
+
+void
+Sequencer::llscClearMonitor(const Addr claddr)
+{
+AbstractCacheEntry *line = m_dataCache_ptr->lookup(claddr);
+if (line && line->isLocked(m_version)) {
+line->clearLocked();
+DPRINTF(LLSC, "LLSC Monitor - clearing due to store - "
+  "addr=0x%lx - cpu=%u\n", claddr, m_version);
+}
+}
+
+bool
+Sequencer::llscStoreConditional(const Addr claddr)
+{
+AbstractCacheEntry *line = m_dataCache_ptr->lookup(claddr);
+if (!line)
+return false;
+
+DPRINTF(LLSC, "LLSC Monitor - clearing due to "
+  "store conditional - "
+  "addr=0x%lx - cpu=%u\n",
+  claddr, m_version);
+
+if (line->isLocked(m_version)) {
+line->clearLocked();
+return true;
+} else {
+line->clearLocked();
+return false;
+}
+}
+
+bool
+Sequencer::llscCheckMonitor(const Addr address)
+{
+const Addr claddr = makeLineAddress(address);
+AbstractCacheEntry *line = m_dataCache_ptr->lookup(claddr);
+if (!line)
+return false;
+
+if (line->isLocked(m_version)) {
+return true;
+} else {
+return false;
+}
+}
+
+void
 Sequencer::wakeup()
 {
 assert(drainState() != DrainState::Draining);
@@ -203,62 +262,6 @@
 }

 void
-Sequencer::invalidateSC(Addr address)
-{
-AbstractCacheEntry *e = m_dataCache_ptr->lookup(address);
-// The controller has lost the coherence permissions, hence the lock
-// on the cache line maintained by the cache should be cleared.
-if (e && e->isLocked(m_version)) {
-

[gem5-dev] Change in gem5/gem5[develop]: mem-ruby: LL/SC fixes

2020-03-26 Thread Giacomo Travaglini (Gerrit)

Hello Timothy Hayes,

I'd like you to do a code review. Please visit

https://gem5-review.googlesource.com/c/public/gem5/+/27103

to review the following change.


Change subject: mem-ruby: LL/SC fixes
..

mem-ruby: LL/SC fixes

The implementation for load-linked/store-conditional did not work
correctly for multi-core simulations. Since load-links were treated as
stores, it was not possible for a line to have multiple readers which
often resulted in livelock when using these instructions to implemented
mutexes. This improved implementation treats load-linked instructions
similarly to loads, but places the associated line's address into a
monitor visible to all devices on a system. Writes to a monitored
address ensure the 'linked' property is blown away and any subsequent
store-conditional will fail.

This patch introduces a new RubyRequestType 'Store_Conditional_Failed'
which is a store conditional that has checked the address monitor
and confirmed that it has already failed. For Gem5/Ruby correctness,
this request still needs to go into and return from the mandatory
queue, i.e. the cache controller. As such, the various protocols will
need to recognise this new type--this patch updates MESI_Three_Level,
MESI_Two_Level and MOESI_hammer. Additionally, the transitions of
MESI_Three_Level-L0cache are updated so that line invalidations also
trigger an update to the address monitor.

Change-Id: I19bd74459e26732c92c8b594901936e6439fb073
---
M src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm
M src/mem/ruby/protocol/MESI_Two_Level-L1cache.sm
M src/mem/ruby/protocol/MOESI_hammer-cache.sm
M src/mem/ruby/protocol/RubySlicc_Exports.sm
M src/mem/ruby/protocol/RubySlicc_Types.sm
M src/mem/ruby/system/RubyPort.cc
M src/mem/ruby/system/RubyPort.hh
M src/mem/ruby/system/Sequencer.cc
M src/mem/ruby/system/Sequencer.hh
9 files changed, 333 insertions(+), 97 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..f31c0df 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,48 @@
 }
   }
 } else {
-
   // *** DATA ACCESS ***
   Entry Dcache_entry := getDCacheEntry(in_msg.LineAddress);
+
+  // early out for failed store conditionals
+  if (in_msg.Type == RubyRequestType:Store_Conditional_Failed) {
+  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);
-