]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd: implement basic osd_snap_trim_sleep support
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Wed, 7 Dec 2022 20:41:07 +0000 (20:41 +0000)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Tue, 28 Feb 2023 16:22:05 +0000 (16:22 +0000)
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
src/crimson/osd/osd_operations/snaptrim_event.cc
src/crimson/osd/osd_operations/snaptrim_event.h
src/crimson/osd/pg.cc

index 816e06e44a6d305f49eda0f02c19bb77b64c6741..960af069e0c88ad3b6c7ddafc785f9198048cdac 100644 (file)
@@ -64,6 +64,7 @@ void SnapTrimEvent::print(std::ostream &lhs) const
   lhs << "SnapTrimEvent("
       << "pgid=" << pg->get_pgid()
       << " snapid=" << snapid
+      << " needs_pause=" << needs_pause
       << ")";
 }
 
@@ -155,11 +156,28 @@ seastar::future<seastar::stop_iteration> SnapTrimEvent::with_pg(
           wait_subop
         ).then_interruptible([this] {
           logger().debug("{}: awaiting completion", *this);
-          return subop_blocker.wait_completion().then([this] {
-            logger().debug("{}: all completed", *this);
-            return interruptor::make_ready_future<seastar::stop_iteration>(
-              seastar::stop_iteration::no);
+          return subop_blocker.wait_completion();
+        }).then_interruptible([this] {
+          if (!needs_pause) {
+            return interruptor::now();
+          }
+          // let's know operators we're waiting
+          return enter_stage<interruptor>(
+            wait_trim_timer
+          ).then_interruptible([this] {
+            using crimson::common::local_conf;
+            const auto time_to_sleep =
+              local_conf().template get_val<double>("osd_snap_trim_sleep");
+            logger().debug("{}: time_to_sleep {}", *this, time_to_sleep);
+            // TODO: this logic should be more sophisticated and distinguish
+            // between SSDs, HDDs and the hybrid case
+            return seastar::sleep(
+              std::chrono::milliseconds(std::lround(time_to_sleep * 1000)));
           });
+        }).then_interruptible([this] {
+          logger().debug("{}: all completed", *this);
+          return interruptor::make_ready_future<seastar::stop_iteration>(
+            seastar::stop_iteration::no);
         });
       });
     });
index 7f5d2e5910df0aecbca5b96aef7a4c9c1edc682a..58eacb35a740682ee9a240874feebdc82a0fd038 100644 (file)
@@ -32,10 +32,14 @@ class SnapTrimEvent final : public PhasedOperationT<SnapTrimEvent> {
 public:
   static constexpr OperationTypeCode type = OperationTypeCode::snaptrim_event;
 
-  SnapTrimEvent(Ref<PG> pg, SnapMapper& snap_mapper, snapid_t snapid)
+  SnapTrimEvent(Ref<PG> pg,
+                SnapMapper& snap_mapper,
+                const snapid_t snapid,
+                const bool needs_pause)
     : pg(std::move(pg)),
       snap_mapper(snap_mapper),
-      snapid(snapid) {}
+      snapid(snapid),
+      needs_pause(needs_pause) {}
 
   void print(std::ostream &) const final;
   void dump_detail(ceph::Formatter* f) const final;
@@ -68,10 +72,18 @@ private:
     static constexpr auto type_name = "SnapTrimEvent::wait_subop";
   } wait_subop;
 
+  // an instantiator can instruct us to go over this stage and then
+  // wait for the future to implement throttling. It is implemented
+  // that way to for the sake of tracking ops.
+  struct WaitTrimTimer : OrderedExclusivePhaseT<WaitTrimTimer> {
+    static constexpr auto type_name = "SnapTrimEvent::wait_trim_timer";
+  } wait_trim_timer;
+
   PipelineHandle handle;
   Ref<PG> pg;
   SnapMapper& snap_mapper;
   const snapid_t snapid;
+  const bool needs_pause;
 
 public:
   PipelineHandle& get_handle() { return handle; }
@@ -84,6 +96,7 @@ public:
     CommonPGPipeline::GetOBC::BlockingEvent,
     CommonPGPipeline::Process::BlockingEvent,
     WaitSubop::BlockingEvent,
+    WaitTrimTimer::BlockingEvent,
     CompletionEvent
   > tracking_events;
 };
index c8ddbd00122a831d328be69f7ed1bfff0f09ad3c..69076ad82669fefb9af4174a48863be7a98b722f 100644 (file)
@@ -457,13 +457,15 @@ void PG::on_active_actmap()
     [this] {
       const auto to_trim = snap_trimq.range_start();
       snap_trimq.erase(to_trim);
-      return seastar::repeat([to_trim, this] {
+      const auto needs_pause = !snap_trimq.empty();
+      return seastar::repeat([to_trim, needs_pause, this] {
         logger().debug("{}: going to start SnapTrimEvent, to_trim={}",
                        *this, to_trim);
         return shard_services.start_operation<SnapTrimEvent>(
           this,
           snap_mapper,
-          to_trim).second;
+          to_trim,
+          needs_pause).second;
       }).then([this, trimmed=to_trim] {
         logger().debug("{}: trimmed snap={}", *this, trimmed);
       });