Skip to content

Commit 74b2920

Browse files
committed
[dma] Return unfilled superpages on dma stop
1 parent f636073 commit 74b2920

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

src/Cru/CruDmaChannel.cxx

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,26 +159,51 @@ void CruDmaChannel::setBufferNonReady()
159159

160160
void CruDmaChannel::deviceStopDma()
161161
{
162+
// Block further pushes; transfer queue has no available place anymore
163+
mLinkQueuesTotalAvailable = 0;
164+
165+
// Disable data taking
162166
setBufferNonReady();
163167
getBar2()->disableDataTaking();
168+
169+
// Transfer remaining (filled) superpages to ReadyQueue
164170
int moved = 0;
165171
for (auto& link : mLinks) {
166172
int32_t superpageCount = getBar()->getSuperpageCount(link.id);
167173
uint32_t amountAvailable = superpageCount - link.superpageCounter;
168174
//log((format("superpageCount %1% amountAvailable %2%") % superpageCount % amountAvailable).str());
169-
for (uint32_t i = 0; i < amountAvailable; ++i) {
175+
while (amountAvailable) {
170176
if (mReadyQueue.size() >= READY_QUEUE_CAPACITY) {
171177
break;
172178
}
173179

174-
if (!link.queue.empty()) { // care for the extra filled superpage
175-
transferSuperpageFromLinkToReady(link);
180+
if (!link.queue.empty()) {
181+
transferSuperpageFromLinkToReady(link, true);
176182
moved++;
177183
}
184+
amountAvailable--;
178185
}
179-
assert(link.queue.empty());
180186
}
181-
assert(mLinkQueuesTotalAvailable == LINK_QUEUE_CAPACITY * mLinks.size());
187+
188+
// Return any superpages that have been pushed up in the meantime but won't get filled
189+
for (auto& link : mLinks) {
190+
while (!link.queue.empty()) {
191+
link.queue.front().setReceived(0);
192+
link.queue.front().setReady(true);
193+
mReadyQueue.push_back(link.queue.front());
194+
link.queue.pop_front();
195+
}
196+
197+
if (!link.queue.empty()) {
198+
log((format("Superpage queue of link %1% not empty after DMA stop. Superpages unclaimed.") % link.id).str(),
199+
InfoLogger::InfoLogger::Error);
200+
}
201+
}
202+
203+
if (getTransferQueueAvailable()) {
204+
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Transfer queue not full when it should be"));
205+
}
206+
182207
log((format("Moved %1% remaining superpage(s) to ready queue") % moved).str());
183208
}
184209

@@ -270,7 +295,7 @@ void CruDmaChannel::pushSuperpageToLink(Link& link, const Superpage& superpage)
270295
link.queue.push_back(superpage);
271296
}
272297

273-
void CruDmaChannel::transferSuperpageFromLinkToReady(Link& link)
298+
void CruDmaChannel::transferSuperpageFromLinkToReady(Link& link, bool stopping)
274299
{
275300
if (link.queue.empty()) {
276301
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Could not transfer Superpage from link to ready queue, link queue is empty"));
@@ -288,7 +313,9 @@ void CruDmaChannel::transferSuperpageFromLinkToReady(Link& link)
288313
mReadyQueue.push_back(link.queue.front());
289314
link.queue.pop_front();
290315
link.superpageCounter++;
291-
mLinkQueuesTotalAvailable++;
316+
if (!stopping) {
317+
mLinkQueuesTotalAvailable++;
318+
}
292319
}
293320

294321
void CruDmaChannel::fillSuperpages()

src/Cru/CruDmaChannel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class CruDmaChannel final : public DmaChannelPdaBase
115115
void pushSuperpageToLink(Link& link, const Superpage& superpage);
116116

117117
/// Mark the front superpage of a link ready and transfer it to the ready queue
118-
void transferSuperpageFromLinkToReady(Link& link);
118+
void transferSuperpageFromLinkToReady(Link& link, bool stopping = false);
119119

120120
/// Enable debug mode by writing to the appropriate CRU register
121121
void enableDebugMode();

0 commit comments

Comments
 (0)