Repository navigation
Add Silk::FiberTaskTracker and keep the scheduler thread name when a fiber joins a thread group - #131272
Add Silk::FiberTaskTracker and keep the scheduler thread name when a fiber joins a thread group#131272kolsha wants to merge 2 commits into
Silk::FiberTaskTracker and keep the scheduler thread name when a fiber joins a thread group#131272Conversation
…roup A fiber has a `ThreadStatus` without an OS thread of its own, so `setThreadName` in `ThreadGroupSwitcher` renamed the Silk scheduler thread it happened to run on, and the restore wrote the wrong name back after the fiber migrated. Attach and detach already skip OS-thread work for such statuses (`ThreadStatusExt.cpp`); the switcher now skips the rename and its restore the same way, and `ThreadStatus::boundToOSThread` becomes public for it. Test: inside a fiber the scheduler thread keeps its name while a `ThreadGroupSwitcher` attaches the fiber to a group, also when it borrows a status that owns a group.
`Silk::FiberTaskTracker` runs tasks in Silk fibers, at most `max_inflight` at once, for a waiting fiber or thread, with a subset of the interface of `TaskTracker` (`add`, `waitAll`, `safeWaitAll`). Its slots are allocated up front, as in `ThreadPoolTaskTracker.cpp`, so that a caller can create it before it starts work that has to be undone on failure. It waits for any finished task through `silk::FiberFuture::waitForMultiple`, tracks only started tasks, and releases a task's callback and thread group before the waiter resumes, as in `threadPoolCallbackRunner.h`. A failed `Silk::spawn` and a fiber that ends without running its task are reported as `CANNOT_SCHEDULE_TASK`, and a tracker without slots is a `LOGICAL_ERROR`. Tests: gtests for thread group accounting in a real fiber, the first error, the inflight limit, and both start failures through the new failpoints `silk_fiber_task_tracker_spawn_failure` and `silk_fiber_main_failure`.
|
Workflow [PR], commit [e62bbe7] Summary: ⏳ AI ReviewSummaryAdds Missing context / blind spots
Findings❌ Blockers
Tests
Final Verdict❌ Block. Make partial |
| /// Fails as a failed `ThreadStatus` construction would, before the task runs. | ||
| fiu_do_on(DB::FailPoints::silk_fiber_main_failure, | ||
| { | ||
| throw DB::Exception(DB::ErrorCodes::FAULT_INJECTED, "Injected failure before running a fiber task"); | ||
| }); |
There was a problem hiding this comment.
[Blocker] Real ThreadStatus construction failures can leave current_thread dangling
This failpoint throws before construction, so it misses a failure after ThreadStatus.cpp:199 publishes current_thread = this. In a non-sanitized build, the subsequent first-use construction of alt_stack at line 215 can throw from aligned_alloc or guard-page installation. The partially constructed status then loses its members without running ~ThreadStatus, leaving current_thread pointing at the destroyed stack object. The catch here logs through that status, and onFiberSuspend subsequently dereferences it in publishUntrackedMemory, causing undefined behavior instead of safely reporting CANNOT_SCHEDULE_TASK.
Please roll back current_thread when construction fails (before member destruction), and exercise a failure after publication. The current pre-construction injection cannot establish the advertised startup-failure guarantee.
| try | ||
| { | ||
| /// Fibers are not renamed, so the thread name is not used. | ||
| DB::ThreadGroupSwitcher switcher(std::move(slot.thread_group), DB::ThreadName::UNKNOWN); |
There was a problem hiding this comment.
[Major] Attaching the task still leaks jemalloc profiling state between fibers
ThreadGroupSwitcher reaches ThreadStatus::applyQuerySettings, whose jemalloc section (ThreadStatusExt.cpp:404–412) still changes thread.prof.active and collect_local_profiles_in_trace_log on the scheduler's OS thread. Neither is saved by FiberLocalStorage. With jemalloc_enable_profiler or jemalloc_collect_profile_samples_in_trace_log enabled, a task that waits for I/O leaves profiling enabled for unrelated fibers running on that worker. If it resumes elsewhere, detachFromGroup resets the new worker instead, leaving the original worker modified; another task's detach can also disable profiling underneath the suspended task. Skipping the thread rename does not isolate these settings.
Please make these profiling settings effective per fiber across suspend/resume, or explicitly reject them for fiber tasks. Add focused coverage with interleaved profiled and unprofiled tasks.
Build profile diff (arm_release)Comparing ✅ No significant changes. Binary sizes
The official master build is compiled with Object file sizes7 object files changed (+74.37 KiB total), 1 added.
711 more object files are built by the master warmup baseline only (it builds every object-file target, a pull request build only Slowest function optimization changes (ThinLTO)Median per-function time ratio to the master baseline:
Compile time of recompiled translation units132 translation units recompiled, 932 s compile time in total, 131 of them have a recent master baseline. |
Adds
Silk::FiberTaskTracker, which runs tasks in Silk fibers, at mostmax_inflightat once, for a waiting fiber or thread, and stopsThreadGroupSwitcherfrom renaming the scheduler thread when a fiber joins a thread group.TaskTrackerruns parallel work on a thread pool, so every task holds a pool thread while it waits for I/O. Running such work in fibers needs an executor with the same calling pattern that stays correct on every failure path. Each fiber task joins the caller's thread group, which exposed thatThreadGroupSwitchertreated a fiber'sThreadStatusas if it owned the OS thread it ran on.ThreadPoolTaskTracker.cpp, so a caller can create the tracker before it starts work that has to be undone. Only started tasks are tracked and waited for; a failedSilk::spawnand a fiber that ends without running its task are reported asCANNOT_SCHEDULE_TASK, and a tracker without slots is aLOGICAL_ERROR.TaskTracker. The interface is a subset of it:add,waitAll,safeWaitAll. When every slot is busy,addwaits for any finished task throughsilk::FiberFuture::waitForMultipleand rethrows its exception. A task releases its callback and thread group before the waiter resumes, as inthreadPoolCallbackRunner.h.ThreadStatushas no OS thread of its own, soThreadGroupSwitcherrenamed whichever scheduler thread the fiber ran on and wrote the wrong name back after the fiber migrated. It now skips the rename and its restore for such statuses, as attach and detach already do (ThreadStatusExt.cpp);ThreadStatus::boundToOSThreadbecomes public for it.No caller in this repository uses the tracker yet. Tests: gtests for thread group accounting in a real fiber, the first error, the inflight limit, both start failures through the new failpoints
silk_fiber_task_tracker_spawn_failureandsilk_fiber_main_failure, and the scheduler thread name in a fiber, both when the switcher attaches and when it borrows a status that owns a group.Changelog category (leave one):
Workflow [PR]
Sync PR [sync-upstream/pr/131272]