Gabe Black has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/69437?usp=email )
Change subject: dev: Add an "abortPending" method to the DMA port class.
......................................................................
dev: Add an "abortPending" method to the DMA port class.
This will abort any pending transactions that have been given to the
port.
M src/dev/dma_device.cc
M src/dev/dma_device.hh
2 files changed, 86 insertions(+), 17 deletions(-)
Approvals:
Gabe Black: Looks good to me, approved; Looks good to me, approved
kokoro: Regressions pass
diff --git a/src/dev/dma_device.cc b/src/dev/dma_device.cc
index ebda635..24e931e 100644
--- a/src/dev/dma_device.cc
+++ b/src/dev/dma_device.cc
@@ -81,6 +81,8 @@
void
DmaPort::handleResp(DmaReqState *state, Addr addr, Addr size, Tick delay)
{
assert(pendingCount != 0);
pendingCount--;
// If this request was aborted, check to see if its in flight
accesses
// have finished. There may be packets for more than one request in
// flight at a time, so check for finished requests, or no more
// packets.
if (all_bytes || pendingCount == 0) {
// If yes, signal its abort event (if any) and delete the
state.
if (state->abortEvent) {
device->schedule(state->abortEvent, curTick());
}
delete state;
}
// If we have reached the end of this DMA request, then signal the
// completion and delete the sate.
if (state->completionEvent) {
delay += state->delay;
device->schedule(state->completionEvent, curTick() + delay);
@@ -166,8 +179,9 @@
void
DmaPort::recvReqRetry()
{
retryPending = false;
if (transmitList.size())
trySendTimingReq();
}
void
@@ -184,7 +198,6 @@
transmitList.push_back(
new DmaReqState(cmd, addr, cacheLineSize, size,
data, flag, requestorId, sid, ssid, event, delay));
pendingCount++;
// In zero time, also initiate the sending of the packets for the
request
// we have just created. For atomic this involves actually completing
all
@@ -201,6 +214,42 @@
}
void
+DmaPort::abortPending()
+{
delete inRetry;
inRetry = nullptr;
auto *state = transmitList.front();
if (state->numBytes != state->gen.complete()) {
// In flight packets refer to the transmission at the front of
the
// list, and not a transmission whose packets have all been
sent
// but not completed. Preserve the state so the packets don't
have
// dangling pointers.
transmitList.pop_front();
state->aborted = true;
}
auto *state = transmitList.front();
if (state->abortEvent)
device->schedule(state->abortEvent, curTick());
delete state;
transmitList.pop_front();
device->deschedule(sendEvent);
signalDrainDone();
+}
+
+void
DmaPort::trySendTimingReq()
{
// Send the next packet for the first DMA request on the transmit list,
@@ -216,14 +265,17 @@
// Check if this was the last packet now, since hypothetically the
packet
// response may come immediately, and state may be deleted.
bool last = state->gen.last();
pendingCount++;
retryPending = true;
inRetry = pkt;
state->gen.next();
// If that was the last packet from this request, pop it from the
list.
if (last)
transmitList.pop_front();
else
state->gen.next();
DPRINTF(DMA, "-- Done\n");
// If there is more to do, then do so.
if (!transmitList.empty()) {
@@ -236,8 +288,8 @@
DPRINTF(DMA, "-- Failed, waiting for retry\n");
}
transmitList.size(), inRetry ? 1 : 0);
DPRINTF(DMA, "TransmitList: %d, retryPending: %d\n",
transmitList.size(), retryPending ? 1 : 0);
}
bool
@@ -246,6 +298,7 @@
PacketPtr pkt = state->createPacket();
DPRINTF(DMA, "Sending DMA for addr: %#x size: %d\n",
state->gen.addr(), state->gen.size());
pendingCount++;
Tick lat = sendAtomic(pkt);
// Check if we're done, since handleResp may delete state.
@@ -258,6 +311,7 @@
DmaPort::sendAtomicBdReq(DmaReqState *state)
{
bool done = false;
pendingCount++;
auto bd_it = memBackdoors.contains(state->gen.addr());
if (bd_it == memBackdoors.end()) {
@@ -336,7 +390,7 @@
if (sys->isTimingMode()) {
// If we are either waiting for a retry or are still waiting after
// sending the last packet, then do not proceed.
if (inRetry || sendEvent.scheduled()) {
if (retryPending || sendEvent.scheduled()) {
DPRINTF(DMA, "Can't send immediately, waiting to send\n");
return;
}
diff --git a/src/dev/dma_device.hh b/src/dev/dma_device.hh
index 2a3468c..92b44bf 100644
--- a/src/dev/dma_device.hh
+++ b/src/dev/dma_device.hh
@@ -85,6 +85,12 @@
* complete. */
Event *completionEvent;
/** Event to call on the device when this transaction is aborted.
*/
Event *abortEvent;
/** Whether this request was aborted. */
bool aborted = false;
/** Total number of bytes that this transaction involves. */
const Addr totBytes;
@@ -115,8 +121,9 @@
DmaReqState(Packet::Command _cmd, Addr addr, Addr chunk_sz, Addr
tb,
uint8_t *_data, Request::Flags _flags, RequestorID _id,
uint32_t _sid, uint32_t _ssid, Event *ce, Tick _delay)
: completionEvent(ce), totBytes(tb), delay(_delay),
uint32_t _sid, uint32_t _ssid, Event *ce, Tick _delay,
Event *ae=nullptr)
: completionEvent(ce), abortEvent(ae), totBytes(tb),
delay(_delay),
gen(addr, tb, chunk_sz), data(_data), flags(_flags), id(_id),
sid(_sid), ssid(_ssid), cmd(_cmd)
{}
@@ -168,6 +175,11 @@
/** The packet (if any) waiting for a retry to send. */
PacketPtr inRetry = nullptr;
* Whether the other side expects us to wait for a retry. We may have
* decided not to actually send the packet by the time we get the
retry.
*/
bool retryPending = false;
/** Default streamId */
const uint32_t defaultSid;
@@ -195,6 +207,9 @@
uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay,
Request::Flags flag=0);
// Abort and remove any pending DMA transmissions.
void abortPending();
bool dmaPending() const { return pendingCount > 0; }
DrainState drain() override;
--
To view, visit
https://gem5-review.googlesource.com/c/public/gem5/+/69437?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ie5f2c702530656a0c4590461369d430abead14cd
Gerrit-Change-Number: 69437
Gerrit-PatchSet: 3
Gerrit-Owner: Gabe Black gabe.black@gmail.com
Gerrit-Reviewer: Gabe Black gabe.black@gmail.com
Gerrit-Reviewer: Giacomo Travaglini giacomo.travaglini@arm.com
Gerrit-Reviewer: Jui-min Lee fcrh@google.com
Gerrit-Reviewer: kokoro noreply+kokoro@google.com
Gerrit-CC: Gabe Black gabeblack@google.com
Gerrit-MessageType: merged