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