summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mem/ruby/system/DMASequencer.cc8
-rw-r--r--src/mem/ruby/system/RubyPort.cc24
2 files changed, 23 insertions, 9 deletions
diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc
index fbaf5f1d1..e8e279043 100644
--- a/src/mem/ruby/system/DMASequencer.cc
+++ b/src/mem/ruby/system/DMASequencer.cc
@@ -116,9 +116,13 @@ DMASequencer::issueNext()
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");
- ruby_hit_callback(active_request.pkt);
+ //
+ // 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);
return;
}
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index f4bc5c95c..c79154566 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -305,16 +305,26 @@ RubyPort::ruby_hit_callback(PacketPtr pkt)
// 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;
}
}