Gabriel B. has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/67658?usp=email )
Change subject: mem-ruby: AbstractController can send retry req to mem
controller
......................................................................
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+kok...@google.com>
Reviewed-by: Bobby Bruce <bbr...@ucdavis.edu>
Maintainer: Bobby Bruce <bbr...@ucdavis.edu>
---
M src/mem/ruby/slicc_interface/AbstractController.cc
M src/mem/ruby/slicc_interface/AbstractController.hh
2 files changed, 51 insertions(+), 7 deletions(-)
Approvals:
kokoro: Regressions pass
Bobby Bruce: Looks good to me, approved; Looks good to me, approved
diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc
b/src/mem/ruby/slicc_interface/AbstractController.cc
index 2d10422..f7b01cf 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.cc
+++ b/src/mem/ruby/slicc_interface/AbstractController.cc
@@ -62,8 +62,10 @@
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 @@
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 @@
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 @@
}
+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
diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh
b/src/mem/ruby/slicc_interface/AbstractController.hh
index a5ab5c2..7fdb88b 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.hh
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh
@@ -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 @@
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 @@
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 @@
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 @@
NetDest downstreamDestinations;
NetDest upstreamDestinations;
+ void sendRetryRespToMem();
+ MemberEventWrapper<&AbstractController::sendRetryRespToMem>
mRetryRespEvent;
+
public:
struct ControllerStats : public statistics::Group
{
--
To view, visit
https://gem5-review.googlesource.com/c/public/gem5/+/67658?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I261bb4593c126208c98825e54f538638d818d16b
Gerrit-Change-Number: 67658
Gerrit-PatchSet: 6
Gerrit-Owner: Gabriel B. <gabriel.bus...@arteris.com>
Gerrit-Reviewer: Bobby Bruce <bbr...@ucdavis.edu>
Gerrit-Reviewer: Gabriel B. <gabriel.bus...@arteris.com>
Gerrit-Reviewer: Jason Lowe-Power <ja...@lowepower.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-CC: kokoro <noreply+kok...@google.com>
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org