changeset 436d5dde4bb7 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=436d5dde4bb7
description:
ruby: fix deadlock bug in banked array resource checks
The Ruby banked array resource checks (initiated from SLICC) did a
check and
allocate at the same time. If a transition needs more than one
resource, then
it might check/allocate resource #1, then fail to get resource #2.
Another
transition might then try to get the same resources, but in reverse
order.
Deadlock.
This patch separates resource checking and resource reservation into two
steps to avoid deadlock.
diffstat:
src/mem/protocol/RubySlicc_Types.sm | 2 +-
src/mem/ruby/structures/BankedArray.cc | 28 +++++++++++++++++++++-------
src/mem/ruby/structures/BankedArray.hh | 2 ++
src/mem/ruby/structures/CacheMemory.cc | 12 +++++++++++-
src/mem/ruby/structures/CacheMemory.hh | 2 +-
5 files changed, 36 insertions(+), 10 deletions(-)
diffs (120 lines):
diff -r 9b3b9be42dd9 -r 436d5dde4bb7 src/mem/protocol/RubySlicc_Types.sm
--- a/src/mem/protocol/RubySlicc_Types.sm Mon Jul 20 09:15:18 2015 -0500
+++ b/src/mem/protocol/RubySlicc_Types.sm Mon Jul 20 09:15:18 2015 -0500
@@ -154,7 +154,7 @@
Cycles getTagLatency();
Cycles getDataLatency();
void setMRU(Address);
- void recordRequestType(CacheRequestType);
+ void recordRequestType(CacheRequestType, Address);
bool checkResourceAvailable(CacheResourceType, Address);
int getCacheSize();
diff -r 9b3b9be42dd9 -r 436d5dde4bb7 src/mem/ruby/structures/BankedArray.cc
--- a/src/mem/ruby/structures/BankedArray.cc Mon Jul 20 09:15:18 2015 -0500
+++ b/src/mem/ruby/structures/BankedArray.cc Mon Jul 20 09:15:18 2015 -0500
@@ -58,13 +58,29 @@
assert(bank < banks);
if (busyBanks[bank].endAccess >= curTick()) {
- if (!(busyBanks[bank].startAccess == curTick() &&
- busyBanks[bank].idx == idx)) {
return false;
+ }
+
+ return true;
+}
+
+void
+BankedArray::reserve(int64 idx)
+{
+ if (accessLatency == 0)
+ return;
+
+ unsigned int bank = mapIndexToBank(idx);
+ assert(bank < banks);
+
+ if(busyBanks[bank].endAccess >= curTick()) {
+ if (busyBanks[bank].startAccess == curTick() &&
+ busyBanks[bank].idx == idx) {
+ // this is the same reservation (can happen when
+ // e.g., reserve the same resource for read and write)
+ return; // OK
} else {
- // We tried to allocate resources twice
- // in the same cycle for the same addr
- return true;
+ panic("BankedArray reservation error");
}
}
@@ -72,8 +88,6 @@
busyBanks[bank].startAccess = curTick();
busyBanks[bank].endAccess = curTick() +
(accessLatency-1) * m_ruby_system->clockPeriod();
-
- return true;
}
unsigned int
diff -r 9b3b9be42dd9 -r 436d5dde4bb7 src/mem/ruby/structures/BankedArray.hh
--- a/src/mem/ruby/structures/BankedArray.hh Mon Jul 20 09:15:18 2015 -0500
+++ b/src/mem/ruby/structures/BankedArray.hh Mon Jul 20 09:15:18 2015 -0500
@@ -70,6 +70,8 @@
// This is so we don't get aliasing on blocks being replaced
bool tryAccess(int64 idx);
+ void reserve(int64 idx);
+
Cycles getLatency() const { return accessLatency; }
};
diff -r 9b3b9be42dd9 -r 436d5dde4bb7 src/mem/ruby/structures/CacheMemory.cc
--- a/src/mem/ruby/structures/CacheMemory.cc Mon Jul 20 09:15:18 2015 -0500
+++ b/src/mem/ruby/structures/CacheMemory.cc Mon Jul 20 09:15:18 2015 -0500
@@ -528,22 +528,32 @@
;
}
+// assumption: SLICC generated files will only call this function
+// once **all** resources are granted
void
-CacheMemory::recordRequestType(CacheRequestType requestType)
+CacheMemory::recordRequestType(CacheRequestType requestType, Address addr)
{
DPRINTF(RubyStats, "Recorded statistic: %s\n",
CacheRequestType_to_string(requestType));
switch(requestType) {
case CacheRequestType_DataArrayRead:
+ if (m_resource_stalls)
+ dataArray.reserve(addressToCacheSet(addr));
numDataArrayReads++;
return;
case CacheRequestType_DataArrayWrite:
+ if (m_resource_stalls)
+ dataArray.reserve(addressToCacheSet(addr));
numDataArrayWrites++;
return;
case CacheRequestType_TagArrayRead:
+ if (m_resource_stalls)
+ tagArray.reserve(addressToCacheSet(addr));
numTagArrayReads++;
return;
case CacheRequestType_TagArrayWrite:
+ if (m_resource_stalls)
+ tagArray.reserve(addressToCacheSet(addr));
numTagArrayWrites++;
return;
default:
diff -r 9b3b9be42dd9 -r 436d5dde4bb7 src/mem/ruby/structures/CacheMemory.hh
--- a/src/mem/ruby/structures/CacheMemory.hh Mon Jul 20 09:15:18 2015 -0500
+++ b/src/mem/ruby/structures/CacheMemory.hh Mon Jul 20 09:15:18 2015 -0500
@@ -117,7 +117,7 @@
void regStats();
bool checkResourceAvailable(CacheResourceType res, Address addr);
- void recordRequestType(CacheRequestType requestType);
+ void recordRequestType(CacheRequestType requestType, Address addr);
public:
Stats::Scalar m_demand_hits;
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev