summaryrefslogtreecommitdiff
path: root/src/mem/ruby/structures
diff options
context:
space:
mode:
authorDavid Hashe <david.hashe@amd.com>2015-07-20 09:15:18 -0500
committerDavid Hashe <david.hashe@amd.com>2015-07-20 09:15:18 -0500
commit21aa5734a0f2c03263e26c66e5cd95ad64c70697 (patch)
tree43cf18ec392aea120c025bf818a0ce30efab201c /src/mem/ruby/structures
parent63a9f10de80a2a117aa06858e65dee2b6654762f (diff)
downloadgem5-21aa5734a0f2c03263e26c66e5cd95ad64c70697.tar.xz
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 (limited to 'src/mem/ruby/structures')
-rw-r--r--src/mem/ruby/structures/BankedArray.cc28
-rw-r--r--src/mem/ruby/structures/BankedArray.hh2
-rw-r--r--src/mem/ruby/structures/CacheMemory.cc12
-rw-r--r--src/mem/ruby/structures/CacheMemory.hh2
4 files changed, 35 insertions, 9 deletions
diff --git a/src/mem/ruby/structures/BankedArray.cc b/src/mem/ruby/structures/BankedArray.cc
index dbde2ab9a..8bc3cf584 100644
--- a/src/mem/ruby/structures/BankedArray.cc
+++ b/src/mem/ruby/structures/BankedArray.cc
@@ -58,13 +58,29 @@ BankedArray::tryAccess(int64 idx)
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 @@ BankedArray::tryAccess(int64 idx)
busyBanks[bank].startAccess = curTick();
busyBanks[bank].endAccess = curTick() +
(accessLatency-1) * m_ruby_system->clockPeriod();
-
- return true;
}
unsigned int
diff --git a/src/mem/ruby/structures/BankedArray.hh b/src/mem/ruby/structures/BankedArray.hh
index dbfee9994..438186944 100644
--- a/src/mem/ruby/structures/BankedArray.hh
+++ b/src/mem/ruby/structures/BankedArray.hh
@@ -70,6 +70,8 @@ class BankedArray
// 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 --git a/src/mem/ruby/structures/CacheMemory.cc b/src/mem/ruby/structures/CacheMemory.cc
index c802d8fb6..d08724cff 100644
--- a/src/mem/ruby/structures/CacheMemory.cc
+++ b/src/mem/ruby/structures/CacheMemory.cc
@@ -528,22 +528,32 @@ CacheMemory::regStats()
;
}
+// 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 --git a/src/mem/ruby/structures/CacheMemory.hh b/src/mem/ruby/structures/CacheMemory.hh
index c9c20d8b8..af5e680d8 100644
--- a/src/mem/ruby/structures/CacheMemory.hh
+++ b/src/mem/ruby/structures/CacheMemory.hh
@@ -117,7 +117,7 @@ class CacheMemory : public SimObject
void regStats();
bool checkResourceAvailable(CacheResourceType res, Address addr);
- void recordRequestType(CacheRequestType requestType);
+ void recordRequestType(CacheRequestType requestType, Address addr);
public:
Stats::Scalar m_demand_hits;