Commit 9b29fac9 authored by Dan Melnic's avatar Dan Melnic Committed by Facebook GitHub Bot

IoUringBackend free mempool rework

Summary: IoUringBackend free mempool rework

Reviewed By: kevin-vigor

Differential Revision: D22424753

fbshipit-source-id: 5f8482702ec17561058ea841493e8a5a57b642a6
parent eaf22e04
......@@ -113,27 +113,14 @@ IoUringBackend::IoUringBackend(Options options)
numEntries_ *= 2;
entries_.reset(new IoSqe[numEntries_]);
// timer entry
timerEntry_ = &entries_[0];
timerEntry_->backend_ = this;
timerEntry_ = std::make_unique<IoSqe>(this, false);
timerEntry_->backendCb_ = PollIoBackend::processTimerIoCb;
// signal entry
signalReadEntry_ = &entries_[1];
signalReadEntry_->backend_ = this;
signalReadEntry_ = std::make_unique<IoSqe>(this, false);
signalReadEntry_->backendCb_ = PollIoBackend::processSignalReadIoCb;
// build the free list - first 2 entres are reserved
for (size_t i = 2; i < numEntries_; ++i) {
entries_[i].next_ = (i == (numEntries_ - 1)) ? nullptr : &entries_[i + 1];
entries_[i].backend_ = this;
entries_[i].backendCb_ = PollIoBackend::processPollIoCb;
}
freeHead_ = &entries_[2];
// we need to call the init before adding the timer fd
// so we avoid a deadlock - waiting for the queue to be drained
if (options.useRegisteredFds) {
......@@ -146,7 +133,6 @@ IoUringBackend::IoUringBackend(Options options)
// add the timer fd
if (!addTimerFd() || !addSignalFds()) {
cleanup();
entries_.reset();
throw NotAvailable("io_uring_submit error");
}
}
......@@ -184,6 +170,15 @@ void IoUringBackend::cleanup() {
}
}
// free the entries
timerEntry_.reset();
signalReadEntry_.reset();
while (!freeList_.empty()) {
auto* ioCb = &freeList_.front();
freeList_.pop_front();
delete ioCb;
}
// exit now
::io_uring_queue_exit(&ioRing_);
ioRing_.ring_fd = -1;
......
......@@ -122,7 +122,7 @@ class IoUringBackend : public PollIoBackend {
int submitBusyCheck(int num, WaitForEventsMode waitForEvents);
struct IoSqe : public PollIoBackend::IoCb {
explicit IoSqe(PollIoBackend* backend = nullptr, bool poolAlloc = true)
explicit IoSqe(PollIoBackend* backend = nullptr, bool poolAlloc = false)
: PollIoBackend::IoCb(backend, poolAlloc) {}
~IoSqe() override = default;
......@@ -386,7 +386,8 @@ class IoUringBackend : public PollIoBackend {
}
PollIoBackend::IoCb* allocNewIoCb(const EventCallback& /*cb*/) override {
auto* ret = new IoSqe(this, false);
// allow pool alloc if numIoCbInUse_ < numEntries_
auto* ret = new IoSqe(this, numIoCbInUse_ < numEntries_);
ret->backendCb_ = PollIoBackend::processPollIoCb;
return ret;
......@@ -396,8 +397,6 @@ class IoUringBackend : public PollIoBackend {
size_t submit_internal();
std::unique_ptr<IoSqe[]> entries_;
// io_uring related
struct io_uring_params params_;
struct io_uring ioRing_;
......
......@@ -150,13 +150,17 @@ PollIoBackend::PollIoBackend(Options options)
}
PollIoBackend::~PollIoBackend() {
CHECK(!timerEntry_);
CHECK(!signalReadEntry_);
CHECK(freeList_.empty());
::close(timerFd_);
}
bool PollIoBackend::addTimerFd() {
auto* entry = allocSubmissionEntry(); // this can be nullptr
timerEntry_->prepPollAdd(entry, timerFd_, POLLIN, true /*registerFd*/);
return (1 == submitOne(timerEntry_));
return (1 == submitOne(timerEntry_.get()));
}
bool PollIoBackend::addSignalFds() {
......@@ -164,7 +168,7 @@ bool PollIoBackend::addSignalFds() {
signalReadEntry_->prepPollAdd(
entry, signalFds_.readFd(), POLLIN, false /*registerFd*/);
return (1 == submitOne(signalReadEntry_));
return (1 == submitOne(signalReadEntry_.get()));
}
void PollIoBackend::scheduleTimeout() {
......@@ -336,9 +340,9 @@ size_t PollIoBackend::processSignals() {
PollIoBackend::IoCb* PollIoBackend::allocIoCb(const EventCallback& cb) {
// try to allocate from the pool first
if ((cb.type_ == EventCallback::Type::TYPE_NONE) && (freeHead_ != nullptr)) {
auto* ret = freeHead_;
freeHead_ = freeHead_->next_;
if ((cb.type_ == EventCallback::Type::TYPE_NONE) && (!freeList_.empty())) {
auto* ret = &freeList_.front();
freeList_.pop_front();
numIoCbInUse_++;
return ret;
}
......@@ -364,8 +368,7 @@ void PollIoBackend::releaseIoCb(PollIoBackend::IoCb* aioIoCb) {
if (FOLLY_LIKELY(aioIoCb->poolAlloc_)) {
aioIoCb->event_ = nullptr;
aioIoCb->next_ = freeHead_;
freeHead_ = aioIoCb;
freeList_.push_front(*aioIoCb);
} else {
delete aioIoCb;
}
......
......@@ -117,7 +117,6 @@ class PollIoBackend : public EventBaseBackendBase {
PollIoBackend* backend_;
BackendCb* backendCb_{nullptr};
const bool poolAlloc_;
IoCb* next_{nullptr}; // this is for the free list
Event* event_{nullptr};
FdRegistrationRecord* fdRecord_{nullptr};
size_t useCount_{0};
......@@ -357,9 +356,9 @@ class PollIoBackend : public EventBaseBackendBase {
Options options_;
size_t numEntries_;
IoCb* timerEntry_{nullptr};
IoCb* signalReadEntry_{nullptr};
IoCb* freeHead_{nullptr};
std::unique_ptr<IoCb> timerEntry_;
std::unique_ptr<IoCb> signalReadEntry_;
IoCbList freeList_;
// timer related
int timerFd_{-1};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment