From dadc7f40d04f13cb728552bf26a355326c3b2b07 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 30 Sep 2024 12:39:03 +0200 Subject: [PATCH] msg/async/Event: use eventfd on Linux eventfd is Linux's first-choice tool for waking up I/O event loops. It is faster and more robust than pipes - it does not need a list of pipe buffers, cannot become full, and writing/reading to it is a simple memory access. eventfd has been available since Linux 2.6.22, therefore this patch does not do any configure-time checks and no runtime fallback. If we're __linux__, it must be available. To avoid an ABI breakage, both fields `notify_receive_fd` and `notify_send_fd` remain, both set to the same eventfd value. Signed-off-by: Max Kellermann --- src/msg/async/Event.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/msg/async/Event.cc b/src/msg/async/Event.cc index 16abb1368b0..9e53821b200 100644 --- a/src/msg/async/Event.cc +++ b/src/msg/async/Event.cc @@ -37,6 +37,10 @@ #endif #endif +#ifdef __linux__ +#include +#endif + #define dout_subsys ceph_subsys_ms #undef dout_prefix @@ -48,6 +52,10 @@ class C_handle_notify : public EventCallback { public: C_handle_notify(EventCenter *c, CephContext *cc): center(c), cct(cc) {} void do_request(uint64_t fd_or_id) override { +#ifdef __linux__ + eventfd_t value; + read(fd_or_id, &value, sizeof(value)); +#else char c[256]; int r = 0; do { @@ -61,6 +69,7 @@ class C_handle_notify : public EventCallback { ldout(cct, 1) << __func__ << " read notify pipe failed: " << cpp_strerror(ceph_sock_errno()) << dendl; } } while (r > 0); +#endif } }; @@ -154,6 +163,16 @@ int EventCenter::init(int nevent, unsigned center_id, const std::string &type) if (!driver->need_wakeup()) return 0; +#ifdef __linux__ + int efd = eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC); + if (efd < 0) { + const int e = errno; + lderr(cct) << __func__ << " can't create eventfd: " << cpp_strerror(e) << dendl; + return -e; + } + + notify_receive_fd = notify_send_fd = efd; +#else int fds[2]; #ifdef _WIN32 @@ -177,6 +196,7 @@ int EventCenter::init(int nevent, unsigned center_id, const std::string &type) if (r < 0) { return r; } +#endif return r; } @@ -197,8 +217,12 @@ EventCenter::~EventCenter() if (notify_receive_fd >= 0) compat_closesocket(notify_receive_fd); +#ifndef __linux__ + /* on Linux, notify_receive_fd and notify_send_fd are the same + eventfd, therefore we close only one of them */ if (notify_send_fd >= 0) compat_closesocket(notify_send_fd); +#endif delete driver; if (notify_handler) @@ -347,7 +371,11 @@ void EventCenter::wakeup() return ; ldout(cct, 20) << __func__ << dendl; +#ifdef __linux__ + static constexpr eventfd_t buf = 1; +#else static constexpr char buf = 'c'; +#endif // wake up "event_wait" #ifdef _WIN32 int n = send(notify_send_fd, &buf, sizeof(buf), 0); -- 2.39.5