Skip to content

Commit 6e795e6

Browse files
Add transfer of remaining superpages for CRU backend
1 parent 8388174 commit 6e795e6

File tree

4 files changed

+58
-18
lines changed

4 files changed

+58
-18
lines changed

include/ReadoutCard/DmaChannelInterface.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@ class DmaChannelInterface
3030
/// Call this before pushing pages. May become unneeded in the future.
3131
virtual void startDma() = 0;
3232

33-
/// Stops DMA for the given channel
34-
/// Called automatically on channel closure.
35-
virtual void stopDma() = 0;
36-
3733
/// Resets the channel. Requires the DMA to be stopped.
3834
/// \param resetLevel The depth of the reset
3935
virtual void resetChannel(ResetLevel::type resetLevel) = 0;
@@ -78,6 +74,11 @@ class DmaChannelInterface
7874
/// superpage can be inspected with getSuperpage() or popped with popSuperpage().
7975
virtual int getReadyQueueSize() = 0;
8076

77+
/// Stops DMA for the given channel.
78+
/// Called automatically on channel closure.
79+
/// This moves any remaining superpages to the "ready queue", even if they are not filled.
80+
virtual void stopDma() = 0;
81+
8182
/// Returns the type of the card this DmaChannelInterface is controlling
8283
/// \return The card type
8384
virtual CardType::type getCardType() = 0;

src/CommandLineUtilities/ProgramDmaBench.cxx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,11 @@ class ProgramDmaBench: public Program
344344
}
345345

346346
// Lock-free queues. Usable size is (size-1), so we add 1
347+
/// Queue for passing filled superpages from the push thread to the readout thread
347348
folly::ProducerConsumerQueue<size_t> readoutQueue {static_cast<uint32_t>(mMaxSuperpages) + 1};
349+
/// Queue for free superpages. This starts out as full, then the readout thread consumes them. When superpages
350+
/// arrive, they are passed via the readoutQueue to the readout thread. When the readout thread is done with it,
351+
/// it is put back in the freeQueue.
348352
folly::ProducerConsumerQueue<size_t> freeQueue {static_cast<uint32_t>(mMaxSuperpages) + 1};
349353
for (size_t i = 0; i < mMaxSuperpages; ++i) {
350354
size_t offset = i * mSuperpageSize;
@@ -481,7 +485,7 @@ class ProgramDmaBench: public Program
481485
// Read out pages
482486
int pages = mSuperpageSize / mPageSize;
483487
for (int i = 0; i < pages; ++i) {
484-
auto readoutCount = mReadoutCount.fetch_add(1, std::memory_order_relaxed);
488+
auto readoutCount = fetchAddReadoutCount();
485489
readoutPage(mBufferBaseAddress + offset + i * mPageSize, mPageSize, readoutCount);
486490
}
487491

@@ -501,22 +505,32 @@ class ProgramDmaBench: public Program
501505
lowPriorityFuture.get();
502506
}
503507

508+
/// Atomically fetch and increment the readout count. We do this because it is accessed by multiple threads.
509+
/// Although there is currently only one writer at a time and a regular increment probably would be OK.
510+
uint64_t fetchAddReadoutCount()
511+
{
512+
return mReadoutCount.fetch_add(1, std::memory_order_relaxed);
513+
}
514+
504515
/// Free the pages that were pushed in excess
505516
void freeExcessPages(std::chrono::milliseconds timeout)
506517
{
518+
// First deal with the remaining filled superpages
507519
auto start = std::chrono::steady_clock::now();
508520
int popped = 0;
509521
while ((std::chrono::steady_clock::now() - start) < timeout) {
510522
if (mChannel->getReadyQueueSize() > 0) {
511523
auto superpage = mChannel->getSuperpage();
512524
if (superpage.isFilled()) {
525+
readoutPage(mBufferBaseAddress + superpage.getOffset(), superpage.getSize(), fetchAddReadoutCount());
513526
mChannel->popSuperpage();
514527
popped += superpage.getReceived() / mPageSize;
515528
}
516529
}
517530
}
531+
518532
std::cout << "\n\n";
519-
getLogger() << "Popped " << popped << " excess pages" << endm;
533+
getLogger() << "Popped " << popped << " excess filled pages" << endm;
520534
}
521535

522536
uint32_t get32bitFromPage(uintptr_t pageAddress, size_t index)
@@ -545,9 +559,7 @@ class ProgramDmaBench: public Program
545559
void readoutPage(uintptr_t pageAddress, size_t pageSize, int64_t readoutCount)
546560
{
547561
// Read out to file
548-
if (mOptions.fileOutputAscii || mOptions.fileOutputBin) {
549-
printToFile(pageAddress, pageSize, readoutCount);
550-
}
562+
printToFile(pageAddress, pageSize, readoutCount);
551563

552564
// Data error checking
553565
if (!mOptions.noErrorCheck) {
@@ -815,6 +827,7 @@ class ProgramDmaBench: public Program
815827
}
816828
}
817829

830+
/// Prints the page to a file in ASCII or binary format if such output is enabled
818831
void printToFile(uintptr_t pageAddress, size_t pageSize, int64_t pageNumber)
819832
{
820833
auto page = reinterpret_cast<const volatile uint32_t*>(pageAddress);

src/Cru/CruDmaChannel.cxx

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ auto CruDmaChannel::allowedChannels() -> AllowedChannels {
7979
CruDmaChannel::~CruDmaChannel()
8080
{
8181
setBufferNonReady();
82+
if (mReadyQueue.size() > 0) {
83+
getLogger() << "Remaining superpages in the ready queue: " << mReadyQueue.size() << InfoLogger::InfoLogger::endm;
84+
}
8285
}
8386

8487
void CruDmaChannel::deviceStartDma()
@@ -136,6 +139,14 @@ void CruDmaChannel::setBufferNonReady()
136139
void CruDmaChannel::deviceStopDma()
137140
{
138141
setBufferNonReady();
142+
for (auto& link : mLinks) {
143+
size_t size = link.queue.size();
144+
for (size_t i = 0; i < size; ++i) {
145+
transferSuperpageFromLinkToReady(link);
146+
}
147+
assert(link.queue.empty());
148+
}
149+
assert(mLinkQueuesTotalAvailable == LINK_QUEUE_CAPACITY * mLinks.size());
139150
}
140151

141152
void CruDmaChannel::deviceResetChannel(ResetLevel::type resetLevel)
@@ -203,9 +214,7 @@ void CruDmaChannel::pushSuperpage(Superpage superpage)
203214
}
204215

205216
// Once we've confirmed the link has a slot available, we push the superpage
206-
mLinkQueuesTotalAvailable--;
207-
link.queue.push_back(superpage);
208-
217+
pushSuperpageToLink(link, superpage);
209218
auto maxPages = superpage.getSize() / Cru::DMA_PAGE_SIZE;
210219
auto busAddress = getBusOffsetAddress(superpage.getOffset());
211220
getBar().pushSuperpageDescriptor(link.id, maxPages, busAddress);
@@ -229,6 +238,22 @@ auto CruDmaChannel::popSuperpage() -> Superpage
229238
return superpage;
230239
}
231240

241+
void CruDmaChannel::pushSuperpageToLink(Link& link, const Superpage& superpage)
242+
{
243+
mLinkQueuesTotalAvailable--;
244+
link.queue.push_back(superpage);
245+
}
246+
247+
void CruDmaChannel::transferSuperpageFromLinkToReady(Link& link)
248+
{
249+
link.queue.front().ready = true;
250+
link.queue.front().received = link.queue.front().size;
251+
mReadyQueue.push_back(link.queue.front());
252+
mLinkQueuesTotalAvailable++;
253+
link.queue.pop_front();
254+
link.superpageCounter++;
255+
}
256+
232257
void CruDmaChannel::fillSuperpages()
233258
{
234259
// Check for arrivals & handle them
@@ -255,12 +280,7 @@ void CruDmaChannel::fillSuperpages()
255280
}
256281

257282
// Front superpage has arrived
258-
link.queue.front().ready = true;
259-
link.queue.front().received = link.queue.front().size;
260-
mReadyQueue.push_back(link.queue.front());
261-
mLinkQueuesTotalAvailable++;
262-
link.queue.pop_front();
263-
link.superpageCounter++;
283+
transferSuperpageFromLinkToReady(link);
264284
}
265285
}
266286
}

src/Cru/CruDmaChannel.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ class CruDmaChannel final : public DmaChannelPdaBase
100100
/// Gets index of next link to push
101101
LinkIndex getNextLinkIndex();
102102

103+
/// Push a superpage to a link
104+
void pushSuperpageToLink(Link& link, const Superpage& superpage);
105+
106+
/// Mark the front superpage of a link ready and transfer it to the ready queue
107+
void transferSuperpageFromLinkToReady(Link& link);
108+
103109
/// BAR 0 is needed for DMA engine interaction and various other functions
104110
Pda::PdaBar mPdaBar;
105111

0 commit comments

Comments
 (0)