]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore: wake blocked IO on BackgroundProcess wakeup 69275/head
authorShai Fultheim <shai.fultheim@gmail.com>
Thu, 28 May 2026 07:24:05 +0000 (10:24 +0300)
committerShai Fultheim <shai.fultheim@gmail.com>
Tue, 9 Jun 2026 11:13:49 +0000 (14:13 +0300)
BackgroundProcess::run() blocks on blocking_background when
background_should_run() returns false. When the loop wakes up —
typically because arm_blocking_io_and_wake() kicked it — the loop
re-checks background_should_run(). If that still returns false
(e.g. the cleaner has no pending work), the loop goes straight back
to sleep.

But the wake may also have been triggered by a change in the space-
availability condition (should_block_io) — and there is no path that
re-evaluates blocked user IO when background_should_run is false. The
blocked IO has no future trigger to re-check, and stays stuck until
the next unrelated wake-up happens to come at the right moment, or
never.

Add a maybe_wake_blocked_io() call right after the wake. It's a no-op
when nothing is blocked, and unblocks IO that the space condition has
already cleared otherwise.

Observed in sustained random-write benches that wedged with IO blocked
indefinitely while the cleaner sat idle (should_run=false).

Signed-off-by: Shai Fultheim <shai.fultheim@gmail.com>
src/crimson/os/seastore/extent_placement_manager.cc

index 024dce9402801c2c314ab5230eab021014820a5f..c6110a28de35690a1c54338de0580c7559da3679 100644 (file)
@@ -841,6 +841,12 @@ ExtentPlacementManager::BackgroundProcess::run()
       assert(!blocking_background);
       blocking_background = seastar::promise<>();
       co_await blocking_background->get_future();
+      // After waking (typically because arm_blocking_io_and_wake() kicked us),
+      // give any blocked user IO a chance to proceed. Without this call the
+      // loop would go straight back to sleep if background_should_run() is
+      // still false, but the space condition (should_block_io) may already be
+      // satisfied, leaving blocked IO stuck with no future trigger to re-check.
+      maybe_wake_blocked_io();
     }
   }
   log_state("run(exit)");