changeset 5f69f1b0039e in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=5f69f1b0039e
description:
        Ruby: dma retry fix

        This patch fixes the problem where Ruby would fail to call sendRetry on 
ports
        after it nacked the port.  This patch is particularly helpful for 
bursty dma
        requests which often include several packets.

diffstat:

 src/mem/ruby/system/DMASequencer.cc |   8 ++++++--
 src/mem/ruby/system/RubyPort.cc     |  24 +++++++++++++++++-------
 2 files changed, 23 insertions(+), 9 deletions(-)

diffs (56 lines):

diff -r ebb373fcb206 -r 5f69f1b0039e src/mem/ruby/system/DMASequencer.cc
--- a/src/mem/ruby/system/DMASequencer.cc       Sat Mar 19 14:17:48 2011 -0700
+++ b/src/mem/ruby/system/DMASequencer.cc       Sat Mar 19 14:17:48 2011 -0700
@@ -116,9 +116,13 @@
     assert(m_is_busy == true);
     active_request.bytes_completed = active_request.bytes_issued;
     if (active_request.len == active_request.bytes_completed) {
-        DPRINTF(RubyDma, "DMA request completed\n"); 
+        //
+        // Must unset the busy flag before calling back the dma port because
+        // the callback may cause a previously nacked request to be reissued
+        //
+        DPRINTF(RubyDma, "DMA request completed\n");
+        m_is_busy = false;
         ruby_hit_callback(active_request.pkt);
-        m_is_busy = false;
         return;
     }
 
diff -r ebb373fcb206 -r 5f69f1b0039e src/mem/ruby/system/RubyPort.cc
--- a/src/mem/ruby/system/RubyPort.cc   Sat Mar 19 14:17:48 2011 -0700
+++ b/src/mem/ruby/system/RubyPort.cc   Sat Mar 19 14:17:48 2011 -0700
@@ -305,16 +305,26 @@
     // likely has free resources now.
     //
     if (waitingOnSequencer) {
-        for (std::list<M5Port*>::iterator i = retryList.begin();
-             i != retryList.end(); ++i) {
-            (*i)->sendRetry();
-            (*i)->onRetryList(false);
-            DPRINTF(MemoryAccess,
+        //
+        // Record the current list of ports to retry on a temporary list before
+        // calling sendRetry on those ports.  sendRetry will cause an 
+        // immediate retry, which may result in the ports being put back on the
+        // list. Therefore we want to clear the retryList before calling
+        // sendRetry.
+        //
+        std::list<M5Port*> curRetryList(retryList);
+
+        retryList.clear();
+        waitingOnSequencer = false;
+        
+        for (std::list<M5Port*>::iterator i = curRetryList.begin();
+             i != curRetryList.end(); ++i) {
+            DPRINTF(RubyPort,
                     "Sequencer may now be free.  SendRetry to port %s\n",
                     (*i)->name());
+            (*i)->onRetryList(false);
+            (*i)->sendRetry();
         }
-        retryList.clear();
-        waitingOnSequencer = false;
     }
 }
 
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to