From 27426fab83887cfd48d3eb97be10fd1285918771 Mon Sep 17 00:00:00 2001 From: Matthew Poremba Date: Fri, 8 May 2020 17:16:28 -0500 Subject: [PATCH] mem: Remove infinite queue between Ruby and memory AbstractController sends requests using a QueuedMasterPort which has an implicit buffer which is unbounded. Remove this by changing the port to a MasterPort and implement a retry mechanism for AbstractController. Although the request remains in the MessageBuffer if a retry is needed, the additional retry logic optimizes serviceMemoryQueue slightly and prevents the DRAMCtrl retry stats from being incorrect due to multiple calls to sendTimingReq. Change-Id: I8c592af92a1a499a418f34cfee16dd69d84803ad Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28387 Reviewed-by: Jason Lowe-Power Reviewed-by: Nikos Nikoleris Maintainer: Bradford Beckmann Tested-by: kokoro --- .../slicc_interface/AbstractController.cc | 27 ++++++++++--------- .../slicc_interface/AbstractController.hh | 13 +++++---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc index 59611ae10..b729d26dd 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.cc +++ b/src/mem/ruby/slicc_interface/AbstractController.cc @@ -56,7 +56,7 @@ AbstractController::AbstractController(const Params *p) m_transitions_per_cycle(p->transitions_per_cycle), m_buffer_size(p->buffer_size), m_recycle_latency(p->recycle_latency), m_mandatory_queue_latency(p->mandatory_queue_latency), - memoryPort(csprintf("%s.memory", name()), this, ""), + memoryPort(csprintf("%s.memory", name()), this), addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()) { if (m_version == 0) { @@ -250,12 +250,15 @@ AbstractController::serviceMemoryQueue() // to make more progress. Make sure it wakes up scheduleEvent(Cycles(1)); recvTimingResp(pkt); - } else { + } else if (memoryPort.sendTimingReq(pkt)) { mem_queue->dequeue(clockEdge()); - memoryPort.schedTimingReq(pkt, clockEdge()); // Since the queue was popped the controller may be able // to make more progress. Make sure it wakes up scheduleEvent(Cycles(1)); + } else { + scheduleEvent(Cycles(1)); + delete pkt; + delete s; } return true; @@ -306,11 +309,6 @@ AbstractController::functionalMemoryWrite(PacketPtr pkt) { int num_functional_writes = 0; - // Check the buffer from the controller to the memory. - if (memoryPort.trySatisfyFunctional(pkt)) { - num_functional_writes++; - } - // Update memory itself. memoryPort.sendFunctional(pkt); return num_functional_writes + 1; @@ -369,12 +367,15 @@ AbstractController::MemoryPort::recvTimingResp(PacketPtr pkt) return true; } +void +AbstractController::MemoryPort::recvReqRetry() +{ + controller->serviceMemoryQueue(); +} + AbstractController::MemoryPort::MemoryPort(const std::string &_name, AbstractController *_controller, - const std::string &_label) - : QueuedMasterPort(_name, _controller, reqQueue, snoopRespQueue), - reqQueue(*_controller, *this, _label), - snoopRespQueue(*_controller, *this, false, _label), - controller(_controller) + PortID id) + : MasterPort(_name, _controller, id), controller(_controller) { } diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index 15aff12b1..1577cfa6f 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -228,26 +228,25 @@ class AbstractController : public ClockedObject, public Consumer /** * Port that forwards requests and receives responses from the - * memory controller. It has a queue of packets not yet sent. + * memory controller. */ - class MemoryPort : public QueuedMasterPort + class MemoryPort : public MasterPort { private: - // Packet queues used to store outgoing requests and snoop responses. - ReqPacketQueue reqQueue; - SnoopRespPacketQueue snoopRespQueue; - // Controller that operates this port. AbstractController *controller; public: MemoryPort(const std::string &_name, AbstractController *_controller, - const std::string &_label); + PortID id = InvalidPortID); + protected: // Function for receiving a timing response from the peer port. // Currently the pkt is handed to the coherence controller // associated with this port. bool recvTimingResp(PacketPtr pkt); + + void recvReqRetry(); }; /* Master port to the memory controller. */ -- 2.30.2