]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd/object_context: await in-progress loading (per-obc)
authorMatan Breizman <mbreizma@redhat.com>
Tue, 28 May 2024 13:23:10 +0000 (13:23 +0000)
committerMatan Breizman <mbreizma@redhat.com>
Thu, 13 Jun 2024 12:34:01 +0000 (15:34 +0300)
```
  // obc loading is a concurrent phase. In case this obc is being loaded,
  // make other useres of this obc to await for the loading to complete.
```

Since we now await for loading to finish (in-case in progress), we can
also assert is_loaded().

Fixes: https://tracker.ceph.com/issues/65451
Co-authored-by: Xuehan Xu <xuxuehan@qianxin.com>
Signed-off-by: Matan Breizman <mbreizma@redhat.com>
(cherry picked from commit e456bd7cdd1ad1cd68026cebedd5b1d9d01001f7)

src/crimson/common/interruptible_future.h
src/crimson/osd/object_context.h
src/crimson/osd/object_context_loader.cc
src/crimson/osd/object_context_loader.h

index 27467f2396265d036444a4ef2c977517340585b5..0e2a238edd08f534ddcad3d374289e1735b60844 100644 (file)
@@ -1218,6 +1218,17 @@ public:
            };
   }
 
+  template <typename Lock, typename Func>
+  [[gnu::always_inline]]
+  static auto with_lock(Lock& lock, Func&& func) {
+    return seastar::with_lock(
+      lock,
+      [func=std::move(func),
+       interrupt_condition=interrupt_cond<InterruptCond>.interrupt_cond]() mutable {
+      return call_with_interruption(interrupt_condition, func);
+    });
+  }
+
   template <typename Iterator,
            InvokeReturnsInterruptibleFuture<typename Iterator::reference> AsyncAction>
   [[gnu::always_inline]]
index d651dc912fd52f8134fec62593f8c4b69f551e05..9aa5d60a8003917ab594b480e14eb5def708d1eb 100644 (file)
@@ -70,6 +70,10 @@ public:
   using watch_key_t = std::pair<uint64_t, entity_name_t>;
   std::map<watch_key_t, seastar::shared_ptr<crimson::osd::Watch>> watchers;
 
+  // obc loading is a concurrent phase. In case this obc is being loaded,
+  // make other users of this obc to await for the loading to complete.
+  seastar::shared_mutex loading_mutex;
+
   ObjectContext(hobject_t hoid) : obs(std::move(hoid)) {}
 
   const hobject_t &get_oid() const {
index d8035b440ea1f0f7d5c96c841a28d6551afa0329..9af927806d568f22f3b4e3c700f2d8a47faf5038 100644 (file)
@@ -149,20 +149,23 @@ using crimson::common::local_conf;
              dpp, obc->get_oid(),
              obc->fully_loaded,
              obc->invalidated_by_interval_change);
-    auto loaded =
-      load_obc_iertr::make_ready_future<ObjectContextRef>(obc);
-    if (existed && obc->is_loaded()) {
-      ceph_assert(obc->is_valid());
-      DEBUGDPP("cache hit on {}", dpp, obc->get_oid());
-    } else {
-      DEBUGDPP("cache miss on {}", dpp, obc->get_oid());
-      loaded =
-        obc->template with_promoted_lock<State, IOInterruptCondition>(
-        [obc, this] {
-        return load_obc(obc);
-      });
-    }
-    return loaded;
+    return interruptor::with_lock(obc->loading_mutex,
+    [this, obc, existed, FNAME] {
+      auto loaded =
+        load_obc_iertr::make_ready_future<ObjectContextRef>(obc);
+      if (existed) {
+        ceph_assert(obc->is_valid() && obc->is_loaded());
+        DEBUGDPP("cache hit on {}", dpp, obc->get_oid());
+      } else {
+        DEBUGDPP("cache miss on {}", dpp, obc->get_oid());
+        loaded =
+          obc->template with_promoted_lock<State, IOInterruptCondition>(
+          [obc, this] {
+          return load_obc(obc);
+        });
+      }
+      return loaded;
+    });
   }
 
   ObjectContextLoader::load_obc_iertr::future<>
index 77805e11bc167ec3c504c985c1d672a4fa298b9b..b51e10caf77e8720cd39cb4a15824ba5dafb9615 100644 (file)
@@ -29,6 +29,9 @@ public:
       ::crimson::osd::IOInterruptCondition,
       load_obc_ertr>;
 
+  using interruptor = ::crimson::interruptible::interruptor<
+    ::crimson::osd::IOInterruptCondition>;
+
   using with_obc_func_t =
     std::function<load_obc_iertr::future<> (ObjectContextRef, ObjectContextRef)>;