]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/onode-staged-tree: extend SeastoreNodeExtentManager to test eagain
authorYingxin Cheng <yingxin.cheng@intel.com>
Tue, 18 May 2021 07:55:41 +0000 (15:55 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Fri, 21 May 2021 06:47:48 +0000 (14:47 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_manager.cc
src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_manager.h
src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_manager/seastore.cc
src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_manager/seastore.h

index c379aad3139bea8fd25d54b31cdefcee672d2862..e0c83bf524e550f03534e22feec4ff35b2664241 100644 (file)
@@ -30,9 +30,15 @@ NodeExtentManagerURef NodeExtentManager::create_dummy(bool is_sync)
 }
 
 NodeExtentManagerURef NodeExtentManager::create_seastore(
-    TransactionManager& tm, laddr_t min_laddr)
+    TransactionManager& tm, laddr_t min_laddr, double p_eagain)
 {
-  return NodeExtentManagerURef(new SeastoreNodeExtentManager(tm, min_laddr));
+  if (p_eagain == 0.0) {
+    return NodeExtentManagerURef(
+        new SeastoreNodeExtentManager<false>(tm, min_laddr, p_eagain));
+  } else {
+    return NodeExtentManagerURef(
+        new SeastoreNodeExtentManager<true>(tm, min_laddr, p_eagain));
+  }
 }
 
 }
index 5673db0b4fb727ab89ba738deab30b5cb2fc0082..4304f0ed51e0737d74c83d255d1fd32bd4375b07 100644 (file)
@@ -87,7 +87,7 @@ class NodeExtentManager {
 
   static NodeExtentManagerURef create_dummy(bool is_sync);
   static NodeExtentManagerURef create_seastore(
-      TransactionManager& tm, laddr_t min_laddr = L_ADDR_MIN);
+      TransactionManager& tm, laddr_t min_laddr = L_ADDR_MIN, double p_eagain = 0.0);
 };
 inline std::ostream& operator<<(std::ostream& os, const NodeExtentManager& nm) {
   return nm.print(os);
index d34f99c76ca39de7c2bca3f5b824d0a02aa42b35..528acb8f131579236896ca4ba56062d15fed4aef 100644 (file)
@@ -48,8 +48,8 @@ NodeExtentRef SeastoreNodeExtent::mutate(
     context_t c, DeltaRecorderURef&& _recorder)
 {
   DEBUGT("mutate {:#x} ...", c.t, get_laddr());
-  auto nm = static_cast<SeastoreNodeExtentManager*>(&c.nm);
-  auto extent = nm->get_tm().get_mutable_extent(c.t, this);
+  auto p_handle = static_cast<TransactionManagerHandle*>(&c.nm);
+  auto extent = p_handle->tm.get_mutable_extent(c.t, this);
   auto ret = extent->cast<SeastoreNodeExtent>();
   // A replayed extent may already have an empty recorder, we discard it for
   // simplicity.
index 71c35476b60d15ac6fb73111c268282f481fef4e..da5ed1cde13e1875c3a5c9710bcf2ff784edf289 100644 (file)
@@ -3,6 +3,8 @@
 
 #pragma once
 
+#include <random>
+
 #include "crimson/os/seastore/logging.h"
 
 #include "crimson/os/seastore/onode_manager/staged-fltree/node_extent_manager.h"
@@ -66,18 +68,43 @@ class SeastoreNodeExtent final: public NodeExtent {
   DeltaRecorderURef recorder;
 };
 
-class SeastoreNodeExtentManager final: public NodeExtentManager {
+class TransactionManagerHandle : public NodeExtentManager {
  public:
-  SeastoreNodeExtentManager(TransactionManager& tm, laddr_t min)
-    : tm{tm}, addr_min{min} {};
+  TransactionManagerHandle(TransactionManager& tm) : tm{tm} {}
+  TransactionManager& tm;
+};
+
+template <bool INJECT_EAGAIN=false>
+class SeastoreNodeExtentManager final: public TransactionManagerHandle {
+ public:
+  SeastoreNodeExtentManager(
+      TransactionManager& tm, laddr_t min, double p_eagain)
+      : TransactionManagerHandle(tm), addr_min{min}, p_eagain{p_eagain} {
+    if constexpr (INJECT_EAGAIN) {
+      assert(p_eagain > 0.0 && p_eagain < 1.0);
+    } else {
+      assert(p_eagain == 0.0);
+    }
+  }
+
   ~SeastoreNodeExtentManager() override = default;
-  TransactionManager& get_tm() { return tm; }
+
+  void set_generate_eagain(bool enable) {
+    generate_eagain = enable;
+  }
+
  protected:
   bool is_read_isolated() const override { return true; }
 
   read_ertr::future<NodeExtentRef> read_extent(
       Transaction& t, laddr_t addr, extent_len_t len) override {
     TRACET("reading {}B at {:#x} ...", t, len, addr);
+    if constexpr (INJECT_EAGAIN) {
+      if (trigger_eagain()) {
+        DEBUGT("reading {}B at {:#x}: trigger eagain", t, len, addr);
+        return crimson::ct_error::eagain::make();
+      }
+    }
     return tm.read_extent<SeastoreNodeExtent>(t, addr, len
     ).safe_then([addr, len, &t](auto&& e) {
       TRACET("read {}B at {:#x}", t, e->get_length(), e->get_laddr());
@@ -92,6 +119,12 @@ class SeastoreNodeExtentManager final: public NodeExtentManager {
   alloc_ertr::future<NodeExtentRef> alloc_extent(
       Transaction& t, extent_len_t len) override {
     TRACET("allocating {}B ...", t, len);
+    if constexpr (INJECT_EAGAIN) {
+      if (trigger_eagain()) {
+        DEBUGT("allocating {}B: trigger eagain", t, len);
+        return crimson::ct_error::eagain::make();
+      }
+    }
     return tm.alloc_extent<SeastoreNodeExtent>(t, addr_min, len
     ).safe_then([len, &t](auto extent) {
       DEBUGT("allocated {}B at {:#x}",
@@ -108,6 +141,12 @@ class SeastoreNodeExtentManager final: public NodeExtentManager {
     auto addr = extent->get_laddr();
     auto len = extent->get_length();
     DEBUGT("retiring {}B at {:#x} ...", t, len, addr);
+    if constexpr (INJECT_EAGAIN) {
+      if (trigger_eagain()) {
+        DEBUGT("retiring {}B at {:#x}: trigger eagain", t, len, addr);
+        return crimson::ct_error::eagain::make();
+      }
+    }
     return tm.dec_ref(t, extent).safe_then([addr, len, &t] (unsigned cnt) {
       assert(cnt == 0);
       TRACET("retired {}B at {:#x} ...", t, len, addr);
@@ -117,6 +156,12 @@ class SeastoreNodeExtentManager final: public NodeExtentManager {
   getsuper_ertr::future<Super::URef> get_super(
       Transaction& t, RootNodeTracker& tracker) override {
     TRACET("get root ...", t);
+    if constexpr (INJECT_EAGAIN) {
+      if (trigger_eagain()) {
+        DEBUGT("get root: trigger eagain", t);
+        return crimson::ct_error::eagain::make();
+      }
+    }
     return tm.read_onode_root(t).safe_then([this, &t, &tracker](auto root_addr) {
       TRACET("got root {:#x}", t, root_addr);
       return Super::URef(new SeastoreSuper(t, tracker, root_addr, tm));
@@ -124,14 +169,32 @@ class SeastoreNodeExtentManager final: public NodeExtentManager {
   }
 
   std::ostream& print(std::ostream& os) const override {
-    return os << "SeastoreNodeExtentManager";
+    os << "SeastoreNodeExtentManager";
+    if constexpr (INJECT_EAGAIN) {
+      os << "(p_eagain=" << p_eagain << ")";
+    }
+    return os;
   }
 
  private:
   static LOG_PREFIX(OTree::Seastore);
 
-  TransactionManager& tm;
   const laddr_t addr_min;
+
+  // XXX: conditional members by INJECT_EAGAIN
+  bool trigger_eagain() {
+    if (generate_eagain) {
+      double dice = rd();
+      assert(rd.min() == 0);
+      dice /= rd.max();
+      return dice <= p_eagain;
+    } else {
+      return false;
+    }
+  }
+  bool generate_eagain = true;
+  std::random_device rd;
+  double p_eagain;
 };
 
 }