]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
fixup! crimson/os/seastore: throttle bandwidth to secondary devices
authorXuehan Xu <xuxuehan@qianxin.com>
Thu, 9 Jul 2026 08:59:09 +0000 (16:59 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Fri, 10 Jul 2026 14:24:38 +0000 (22:24 +0800)
src/crimson/os/seastore/extent_placement_manager.h

index e168b35c637425a36c0f7befa9cd59294018baf3..edfab2dcd6b7439e53594b3eeda8fac0acba65f2 100644 (file)
@@ -24,14 +24,22 @@ namespace crimson::os::seastore {
 class Cache;
 
 class TokenBucket {
+  struct Blocker {
+    uint64_t size = 0;
+    seastar::promise<> pr;
+  };
 public:
   TokenBucket(uint64_t mt) :
-    tokens(mt), max_tokens(mt), timer(), sp(std::nullopt) {}
+    tokens(mt), max_tokens(mt), timer() {}
 
   void start() {
     if (max_tokens != 0) {
       tokens = max_tokens;
       timer.set_callback([this] {
+        if (tokens == max_tokens) {
+          return;
+        }
+        assert(tokens < max_tokens);
         tokens += max_tokens / 10;
         if (tokens > max_tokens) {
           tokens = max_tokens;
@@ -56,33 +64,36 @@ public:
     if (max_tokens == 0) {
       return seastar::now();
     }
-    return seastar::repeat([this, size] {
-      if (tokens < size) {
-        if (!sp) {
-          sp.emplace(seastar::shared_promise<>());
-        }
-        return sp->get_shared_future().then([] {
-          return seastar::stop_iteration::no;
-        });
-      } else {
-        tokens -= size;
-        return seastar::make_ready_future<
-          seastar::stop_iteration>(seastar::stop_iteration::yes);
-      }
-    });
+    if (tokens < size) {
+      size -= tokens;
+      tokens = 0;
+      blockers.emplace_back(size);
+      return blockers.back().pr.get_future();
+    } else {
+      tokens -= size;
+      return seastar::now();
+    }
   }
 
 private:
   void do_wake() {
-    if (sp) {
-      sp->set_value();
-      sp.reset();
+    while (!blockers.empty()) {
+      auto &next = blockers.front();
+      if (tokens < next.size) {
+        next.size -= tokens;
+        tokens = 0;
+        break;
+      } else {
+        tokens -= next.size;
+        next.pr.set_value();
+        blockers.pop_front();
+      }
     }
   }
   uint64_t tokens;
   const uint64_t max_tokens;
   seastar::timer<seastar::steady_clock_type> timer;
-  std::optional<seastar::shared_promise<>> sp;
+  std::list<Blocker> blockers;
 };
 
 using TokenBucketRef = std::unique_ptr<TokenBucket>;