IoUringAssmEngn: map StagingBuff w/mmap; reg w/io_uring; add eventFd

StagingBuffer:
We now allocate memory with mmap(MAP_ANONYMOUS) so that we can be
sure it can be pinned with io_uring_register_buffers(). This
ensures that if DMA is possible, it should be usable.

	IoUringAssemblyEngine:
We now register an eventfd with io_uring so that we can listen
for CQEs with boost::asio.
This commit is contained in:
2025-11-05 15:34:23 -04:00
parent 0503705a13
commit 94982d50b9
4 changed files with 103 additions and 8 deletions
+52 -4
View File
@@ -9,6 +9,9 @@
#include <string>
#include <sstream>
#include <algorithm>
#include <sys/mman.h>
#include <sys/uio.h>
#include <unistd.h>
#include "frameAssemblyDesc.h"
@@ -96,6 +99,18 @@ public:
void startAssembly() { assemblingFlag.store(true); }
void stopAssembly() { assemblingFlag.store(false); }
/** EXPLANATION:
* Returns an iovec for io_uring registration.
* The buffer is mmap()-allocated and suitable for IORING_REGISTER_BUFFERS.
*/
struct iovec getIoUringRegisterIoVec() const
{
struct iovec iov;
iov.iov_base = buffer.get();
iov.iov_len = bufferNBytes;
return iov;
}
inline std::string stringify() const
{
std::ostringstream oss;
@@ -111,8 +126,25 @@ public:
private:
void computeSlotStrideAndBufferSize();
// Buffer data
std::unique_ptr<uint8_t[]> buffer;
// Custom deleter for mmap-allocated buffer
struct MmapDeleter
{
size_t size;
MmapDeleter(size_t s) : size(s) {}
void operator()(uint8_t* ptr) const
{
if (ptr != nullptr && size > 0)
{
munmap(ptr, size);
}
}
};
// Buffer data - mmap-allocated for io_uring registration
// Using unique_ptr<uint8_t, MmapDeleter> instead of array syntax
// since we have a custom deleter that knows the size
std::unique_ptr<uint8_t, MmapDeleter> buffer;
size_t bufferNBytes;
// Layout/invariants
@@ -135,7 +167,7 @@ inline StagingBuffer::StagingBuffer(
const InputEngineConstraints& inputEngineConstraints_,
const OutputEngineConstraints& /*outputEngineConstraints*/,
size_t nDgramsPerFrame)
: buffer(nullptr), bufferNBytes(0),
: buffer(nullptr, MmapDeleter(0)), bufferNBytes(0),
nDgramsPerFrame(nDgramsPerFrame), slotStrideNBytes(0),
inputConstraints(inputEngineConstraints_),
assemblingFlag(false)
@@ -148,7 +180,23 @@ assemblingFlag(false)
computeSlotStrideAndBufferSize();
buffer = std::make_unique<uint8_t[]>(bufferNBytes);
/* Allocate buffer using mmap() for io_uring registration
* MAP_ANONYMOUS | MAP_PRIVATE creates anonymous, non-file-backed memory
*/
void* mmapped = mmap(
nullptr, bufferNBytes,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE,
-1, 0);
if (mmapped == MAP_FAILED)
{
throw std::runtime_error(std::string(__func__)
+ ": StagingBuffer: mmap() failed");
}
buffer = std::unique_ptr<uint8_t, MmapDeleter>(
static_cast<uint8_t*>(mmapped), MmapDeleter(bufferNBytes));
currentNBytes.store(0);
// Build FrameAssemblyDesc once