changeset 7c4f1d0a8cff in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=7c4f1d0a8cff
description:
        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:

 src/cpu/minor/lsq.cc |  18 ++++++++++++------
 src/cpu/minor/lsq.hh |   5 +++++
 2 files changed, 17 insertions(+), 6 deletions(-)

diffs (64 lines):

diff -r 953d7b741619 -r 7c4f1d0a8cff src/cpu/minor/lsq.cc
--- a/src/cpu/minor/lsq.cc      Tue Dec 02 06:08:13 2014 -0500
+++ b/src/cpu/minor/lsq.cc      Tue Dec 02 06:08:15 2014 -0500
@@ -730,6 +730,15 @@
 }
 
 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 @@
                     " 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 @@
         /* 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 @@
             break;
           case LSQRequest::StoreBufferIssuing:
             /* In the store buffer */
-            storeBuffer.numUnissuedAccesses--;
+            storeBuffer.countIssuedStore(retryRequest);
             break;
           default:
             assert(false);
diff -r 953d7b741619 -r 7c4f1d0a8cff src/cpu/minor/lsq.hh
--- a/src/cpu/minor/lsq.hh      Tue Dec 02 06:08:13 2014 -0500
+++ b/src/cpu/minor/lsq.hh      Tue Dec 02 06:08:15 2014 -0500
@@ -514,6 +514,11 @@
          *  completely issued to the memory system */
         unsigned int numUnissuedStores() { return numUnissuedAccesses; }
 
+        /** Count a store being issued to memory by decrementing
+         *  numUnissuedAccesses.  Does not count barrier requests as they
+         *  will be handles as barriers are cleared from the buffer */
+        void countIssuedStore(LSQRequestPtr request);
+
         /** Drained if there is absolutely nothing left in the buffer */
         bool isDrained() const { return slots.empty(); }
 
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to