summaryrefslogtreecommitdiff
path: root/src/cpu/minor/lsq.cc
diff options
context:
space:
mode:
authorAndrew Bardsley <Andrew.Bardsley@arm.com>2014-12-02 06:08:15 -0500
committerAndrew Bardsley <Andrew.Bardsley@arm.com>2014-12-02 06:08:15 -0500
commitdf37cad0fdf262ffbfd1b680e7fb8ef7689885ad (patch)
treec21b9cd29013ff22775feabd0e61d64b53a79a10 /src/cpu/minor/lsq.cc
parent98f3e7a3108dc41daae3e9c8ef448cf948b840b1 (diff)
downloadgem5-df37cad0fdf262ffbfd1b680e7fb8ef7689885ad.tar.xz
cpu: Fix retries on barrier/store in Minor's store buffer
This patch fixes a case where a store in Minor's store buffer never leaves the store buffer as it is pre-maturely counted as having been issued, leading to the store buffer idling. LSQ::StoreBuffer::numUnissuedAccesses should count the number of accesses either in memory, or still in the store buffer after being completed. For stores which are also barriers, the store will stay in the store buffer for a cycle after it is completed and will be cleaned up by the barrier clearing code (to ensure that barriers are completed in-order). To acheive this, numUnissuedAccesses is not decremented when a store-barrier is issued to memory, but when its barrier effect is cleared. Without this patch, the correct behaviour happens when a memory transaction is immediately accepted, but not if it needs a retry.
Diffstat (limited to 'src/cpu/minor/lsq.cc')
-rw-r--r--src/cpu/minor/lsq.cc18
1 files changed, 12 insertions, 6 deletions
diff --git a/src/cpu/minor/lsq.cc b/src/cpu/minor/lsq.cc
index 75dbb804a..501620746 100644
--- a/src/cpu/minor/lsq.cc
+++ b/src/cpu/minor/lsq.cc
@@ -730,6 +730,15 @@ LSQ::StoreBuffer::forwardStoreData(LSQRequestPtr load,
}
void
+LSQ::StoreBuffer::countIssuedStore(LSQRequestPtr request)
+{
+ /* Barriers are accounted for as they are cleared from
+ * the queue, not after their transfers are complete */
+ if (!request->isBarrier())
+ numUnissuedAccesses--;
+}
+
+void
LSQ::StoreBuffer::step()
{
DPRINTF(MinorMem, "StoreBuffer step numUnissuedAccesses: %d\n",
@@ -785,10 +794,7 @@ LSQ::StoreBuffer::step()
" system\n", *(request->inst));
if (lsq.tryToSend(request)) {
- /* Barrier are accounted for as they are cleared from
- * the queue, not after their transfers are complete */
- if (!request->isBarrier())
- numUnissuedAccesses--;
+ countIssuedStore(request);
issue_count++;
} else {
/* Don't step on to the next store buffer entry if this
@@ -1198,7 +1204,7 @@ LSQ::recvTimingResp(PacketPtr response)
/* Response to a request from the store buffer */
request->retireResponse(response);
- /* Remove completed requests unless they are barrier (which will
+ /* Remove completed requests unless they are barriers (which will
* need to be removed in order */
if (request->isComplete()) {
if (!request->isBarrier()) {
@@ -1265,7 +1271,7 @@ LSQ::recvRetry()
break;
case LSQRequest::StoreBufferIssuing:
/* In the store buffer */
- storeBuffer.numUnissuedAccesses--;
+ storeBuffer.countIssuedStore(retryRequest);
break;
default:
assert(false);