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 <power.jg@gmail.com> Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Maintainer: Bradford Beckmann <brad.beckmann@amd.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Bradford Beckmann
parent
1e4a6b32b4
commit
27426fab83
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user