From 8fa844383f9c22e758f39ecdda74f70de054ad68 Mon Sep 17 00:00:00 2001 From: Adam Emerson Date: Thu, 21 Dec 2023 14:54:08 -0500 Subject: [PATCH] rgw: Don't hold mutex over yield in LazyFIFO If the FIFO doesn't exist, let clients race to create it, then stash and use whoever wins. Fixes: https://tracker.ceph.com/issues/63373 Signed-off-by: Adam Emerson --- src/rgw/driver/rados/rgw_log_backing.h | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/rgw/driver/rados/rgw_log_backing.h b/src/rgw/driver/rados/rgw_log_backing.h index 3dfdb8ee4ef..6cda9a4ca97 100644 --- a/src/rgw/driver/rados/rgw_log_backing.h +++ b/src/rgw/driver/rados/rgw_log_backing.h @@ -262,12 +262,24 @@ class LazyFIFO { int lazy_init(const DoutPrefixProvider *dpp, optional_yield y) { std::unique_lock l(m); - if (fifo) return 0; - auto r = rgw::cls::fifo::FIFO::create(dpp, ioctx, oid, &fifo, y); - if (r) { - fifo.reset(); + if (fifo) { + return 0; + } else { + l.unlock(); + // FIFO supports multiple clients by design, so it's safe to + // race to create them. + std::unique_ptr fifo_tmp; + auto r = rgw::cls::fifo::FIFO::create(dpp, ioctx, oid, &fifo, y); + if (r) { + return r; + } + l.lock(); + if (!fifo) { + // We won the race + fifo = std::move(fifo_tmp); + } } - return r; + return 0; } public: -- 2.39.5