mem-ruby: AbstractController can send retry req to mem controller

Prior to this patch, when a memory controller was failing at sending a
response to AbstractController, it would not wakeup until the next
request. This patch gives the opportunity to Ruby models to notify
memory response buffer dequeue so that AbstractController can send a
retry request if necessary.

A dequeueMemRspQueue function has been added AbstractController to
automate the dequeue+notify operation.

Note that models that don't notify AbstractController will continue
working as before.

Change-Id: I261bb4593c126208c98825e54f538638d818d16b
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67658
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
This commit is contained in:
Gabriel Busnot
2022-12-05 10:03:13 +00:00
committed by Gabriel B.
parent b4687aa7d9
commit 833afc3451
2 changed files with 51 additions and 7 deletions

View File

@@ -62,8 +62,10 @@ AbstractController::AbstractController(const Params &p)
m_buffer_size(p.buffer_size), m_recycle_latency(p.recycle_latency),
m_mandatory_queue_latency(p.mandatory_queue_latency),
m_waiting_mem_retry(false),
m_mem_ctrl_waiting_retry(false),
memoryPort(csprintf("%s.memory", name()), this),
addrRanges(p.addr_ranges.begin(), p.addr_ranges.end()),
mRetryRespEvent{*this, false},
stats(this)
{
if (m_version == 0) {
@@ -367,11 +369,17 @@ AbstractController::functionalMemoryWrite(PacketPtr pkt)
return num_functional_writes + 1;
}
void
bool
AbstractController::recvTimingResp(PacketPtr pkt)
{
assert(getMemRespQueue());
assert(pkt->isResponse());
auto* memRspQueue = getMemRespQueue();
gem5_assert(memRspQueue);
gem5_assert(pkt->isResponse());
if (!memRspQueue->areNSlotsAvailable(1, curTick())) {
m_mem_ctrl_waiting_retry = true;
return false;
}
std::shared_ptr<MemoryMsg> msg = std::make_shared<MemoryMsg>(clockEdge());
(*msg).m_addr = pkt->getAddr();
@@ -395,8 +403,9 @@ AbstractController::recvTimingResp(PacketPtr pkt)
panic("Incorrect packet type received from memory controller!");
}
getMemRespQueue()->enqueue(msg, clockEdge(), cyclesToTicks(Cycles(1)));
memRspQueue->enqueue(msg, clockEdge(), cyclesToTicks(Cycles(1)));
delete pkt;
return true;
}
Tick
@@ -438,11 +447,33 @@ const
}
void
AbstractController::memRespQueueDequeued() {
if (m_mem_ctrl_waiting_retry && !mRetryRespEvent.scheduled()) {
schedule(mRetryRespEvent, clockEdge(Cycles{1}));
}
}
void
AbstractController::dequeueMemRespQueue() {
auto* q = getMemRespQueue();
gem5_assert(q);
q->dequeue(clockEdge());
memRespQueueDequeued();
}
void
AbstractController::sendRetryRespToMem() {
if (m_mem_ctrl_waiting_retry) {
m_mem_ctrl_waiting_retry = false;
memoryPort.sendRetryResp();
}
}
bool
AbstractController::MemoryPort::recvTimingResp(PacketPtr pkt)
{
controller->recvTimingResp(pkt);
return true;
return controller->recvTimingResp(pkt);
}
void

View File

@@ -61,6 +61,7 @@
#include "mem/ruby/system/CacheRecorder.hh"
#include "params/RubyController.hh"
#include "sim/clocked_object.hh"
#include "sim/eventq.hh"
namespace gem5
{
@@ -100,6 +101,14 @@ class AbstractController : public ClockedObject, public Consumer
virtual MessageBuffer* getMandatoryQueue() const = 0;
virtual MessageBuffer* getMemReqQueue() const = 0;
virtual MessageBuffer* getMemRespQueue() const = 0;
// That function must be called by controller when dequeuing mem resp queue
// for memory controller to receive the retry request in time
void memRespQueueDequeued();
// Or that function can be called to perform both dequeue and notification
// at once.
void dequeueMemRespQueue();
virtual AccessPermission getAccessPermission(const Addr &addr) = 0;
virtual void print(std::ostream & out) const = 0;
@@ -165,7 +174,7 @@ class AbstractController : public ClockedObject, public Consumer
Port &getPort(const std::string &if_name,
PortID idx=InvalidPortID);
void recvTimingResp(PacketPtr pkt);
bool recvTimingResp(PacketPtr pkt);
Tick recvAtomic(PacketPtr pkt);
const AddrRangeList &getAddrRanges() const { return addrRanges; }
@@ -364,6 +373,7 @@ class AbstractController : public ClockedObject, public Consumer
Cycles m_recycle_latency;
const Cycles m_mandatory_queue_latency;
bool m_waiting_mem_retry;
bool m_mem_ctrl_waiting_retry;
/**
* Port that forwards requests and receives responses from the
@@ -411,6 +421,9 @@ class AbstractController : public ClockedObject, public Consumer
NetDest downstreamDestinations;
NetDest upstreamDestinations;
void sendRetryRespToMem();
MemberEventWrapper<&AbstractController::sendRetryRespToMem> mRetryRespEvent;
public:
struct ControllerStats : public statistics::Group
{