diff options
author | Andreas Hansson <andreas.hansson@arm.com> | 2015-03-02 04:00:35 -0500 |
---|---|---|
committer | Andreas Hansson <andreas.hansson@arm.com> | 2015-03-02 04:00:35 -0500 |
commit | f26a28929583f2ed7fb55521e49c3f9bef557c05 (patch) | |
tree | e5d71fc69566b02a394015776b0f3f4e3be81427 /src/mem/ruby | |
parent | 6ebe8d863ae0c5a7799e9421da32593ac35e1cc7 (diff) | |
download | gem5-f26a28929583f2ed7fb55521e49c3f9bef557c05.tar.xz |
mem: Split port retry for all different packet classes
This patch fixes a long-standing isue with the port flow
control. Before this patch the retry mechanism was shared between all
different packet classes. As a result, a snoop response could get
stuck behind a request waiting for a retry, even if the send/recv
functions were split. This caused message-dependent deadlocks in
stress-test scenarios.
The patch splits the retry into one per packet (message) class. Thus,
sendTimingReq has a corresponding recvReqRetry, sendTimingResp has
recvRespRetry etc. Most of the changes to the code involve simply
clarifying what type of request a specific object was accepting.
The biggest change in functionality is in the cache downstream packet
queue, facing the memory. This queue was shared by requests and snoop
responses, and it is now split into two queues, each with their own
flow control, but the same physical MasterPort. These changes fixes
the previously seen deadlocks.
Diffstat (limited to 'src/mem/ruby')
-rw-r--r-- | src/mem/ruby/slicc_interface/AbstractController.cc | 6 | ||||
-rw-r--r-- | src/mem/ruby/slicc_interface/AbstractController.hh | 5 | ||||
-rw-r--r-- | src/mem/ruby/structures/RubyMemoryControl.hh | 2 | ||||
-rw-r--r-- | src/mem/ruby/system/DMASequencer.cc | 2 | ||||
-rw-r--r-- | src/mem/ruby/system/DMASequencer.hh | 2 | ||||
-rw-r--r-- | src/mem/ruby/system/RubyPort.cc | 8 | ||||
-rw-r--r-- | src/mem/ruby/system/RubyPort.hh | 10 |
7 files changed, 21 insertions, 14 deletions
diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc index 6bcbfbcbf..a1d6ab83e 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.cc +++ b/src/mem/ruby/slicc_interface/AbstractController.cc @@ -327,7 +327,9 @@ AbstractController::MemoryPort::recvTimingResp(PacketPtr pkt) AbstractController::MemoryPort::MemoryPort(const std::string &_name, AbstractController *_controller, const std::string &_label) - : QueuedMasterPort(_name, _controller, _queue), - _queue(*_controller, *this, _label), controller(_controller) + : QueuedMasterPort(_name, _controller, reqQueue, snoopRespQueue), + reqQueue(*_controller, *this, _label), + snoopRespQueue(*_controller, *this, _label), + controller(_controller) { } diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index 45d355b3e..f8970fb59 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -181,8 +181,9 @@ class AbstractController : public MemObject, public Consumer class MemoryPort : public QueuedMasterPort { private: - // Packet queue used to store outgoing requests and responses. - MasterPacketQueue _queue; + // Packet queues used to store outgoing requests and snoop responses. + ReqPacketQueue reqQueue; + SnoopRespPacketQueue snoopRespQueue; // Controller that operates this port. AbstractController *controller; diff --git a/src/mem/ruby/structures/RubyMemoryControl.hh b/src/mem/ruby/structures/RubyMemoryControl.hh index 6b1ec1702..78bc74ad5 100644 --- a/src/mem/ruby/structures/RubyMemoryControl.hh +++ b/src/mem/ruby/structures/RubyMemoryControl.hh @@ -109,7 +109,7 @@ class RubyMemoryControl : public AbstractMemory, public Consumer // flow control for the responses being sent back class MemoryPort : public QueuedSlavePort { - SlavePacketQueue queue; + RespPacketQueue queue; RubyMemoryControl& memory; public: diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc index 47a9b13aa..43ef37f08 100644 --- a/src/mem/ruby/system/DMASequencer.cc +++ b/src/mem/ruby/system/DMASequencer.cc @@ -138,7 +138,7 @@ DMASequencer::ruby_hit_callback(PacketPtr pkt) retry = false; DPRINTF(RubyDma,"Sequencer may now be free. SendRetry to port %s\n", slave_port.name()); - slave_port.sendRetry(); + slave_port.sendRetryReq(); } testDrainComplete(); diff --git a/src/mem/ruby/system/DMASequencer.hh b/src/mem/ruby/system/DMASequencer.hh index 7b0fe58c9..bcf586acf 100644 --- a/src/mem/ruby/system/DMASequencer.hh +++ b/src/mem/ruby/system/DMASequencer.hh @@ -66,7 +66,7 @@ class DMASequencer : public MemObject class MemSlavePort : public QueuedSlavePort { private: - SlavePacketQueue queue; + RespPacketQueue queue; RubySystem* ruby_system; bool access_backing_store; diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index b419c491c..dba71952e 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -136,7 +136,8 @@ RubyPort::getSlavePort(const std::string &if_name, PortID idx) RubyPort::PioMasterPort::PioMasterPort(const std::string &_name, RubyPort *_port) - : QueuedMasterPort(_name, _port, queue), queue(*_port, *this) + : QueuedMasterPort(_name, _port, reqQueue, snoopRespQueue), + reqQueue(*_port, *this), snoopRespQueue(*_port, *this) { DPRINTF(RubyPort, "Created master pioport on sequencer %s\n", _name); } @@ -150,7 +151,8 @@ RubyPort::PioSlavePort::PioSlavePort(const std::string &_name, RubyPort::MemMasterPort::MemMasterPort(const std::string &_name, RubyPort *_port) - : QueuedMasterPort(_name, _port, queue), queue(*_port, *this) + : QueuedMasterPort(_name, _port, reqQueue, snoopRespQueue), + reqQueue(*_port, *this), snoopRespQueue(*_port, *this) { DPRINTF(RubyPort, "Created master memport on ruby sequencer %s\n", _name); } @@ -374,7 +376,7 @@ RubyPort::ruby_hit_callback(PacketPtr pkt) DPRINTF(RubyPort, "Sequencer may now be free. SendRetry to port %s\n", (*i)->name()); - (*i)->sendRetry(); + (*i)->sendRetryReq(); } } diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh index 28a416663..2fb31ca09 100644 --- a/src/mem/ruby/system/RubyPort.hh +++ b/src/mem/ruby/system/RubyPort.hh @@ -60,7 +60,8 @@ class RubyPort : public MemObject class MemMasterPort : public QueuedMasterPort { private: - MasterPacketQueue queue; + ReqPacketQueue reqQueue; + SnoopRespPacketQueue snoopRespQueue; public: MemMasterPort(const std::string &_name, RubyPort *_port); @@ -73,7 +74,7 @@ class RubyPort : public MemObject class MemSlavePort : public QueuedSlavePort { private: - SlavePacketQueue queue; + RespPacketQueue queue; RubySystem* ruby_system; bool access_backing_store; @@ -101,7 +102,8 @@ class RubyPort : public MemObject class PioMasterPort : public QueuedMasterPort { private: - MasterPacketQueue queue; + ReqPacketQueue reqQueue; + SnoopRespPacketQueue snoopRespQueue; public: PioMasterPort(const std::string &_name, RubyPort *_port); @@ -114,7 +116,7 @@ class RubyPort : public MemObject class PioSlavePort : public QueuedSlavePort { private: - SlavePacketQueue queue; + RespPacketQueue queue; public: PioSlavePort(const std::string &_name, RubyPort *_port); |