Repository navigation
Conversation
Introduce a new per-cgroup file "cost.boost" that allows temporarily boosting an io.cost cgroup. Writing a duration in microseconds to the file enables boost mode for that cgroup. When a cgroup is boosted, iocost skips surplus evaluation for it and restores its inuse weight to active, ensuring the boosted cgroup keeps its full IO share during the boost period. Signed-off-by: ecjtusbs <ecjtusbs@foxmail.com>
Reviewer's GuideIntroduces a non-root Sequence diagram for the cost.boost cgroup interfacesequenceDiagram
actor User
participant CgroupFS
participant Iocost
participant IocostTimer
User->>CgroupFS: write cost.boost duration_us
CgroupFS->>Iocost: ioc_boost_write(buf)
Iocost->>Iocost: kstrtou64(strim(buf), 10, duration_us)
alt duration_us > MAX_BOOST_US
Iocost-->>CgroupFS: -EINVAL
else duration_us == 0
Iocost->>Iocost: WRITE_ONCE(boost_deadline, 0)
Iocost-->>CgroupFS: nbytes
else valid duration
Iocost->>Iocost: WRITE_ONCE(boost_deadline, deadline)
Iocost-->>CgroupFS: nbytes
end
IocostTimer->>Iocost: ioc_timer_fn()
Iocost->>Iocost: READ_ONCE(boost_deadline)
alt boost_deadline > now
Iocost->>Iocost: __propagate_weights(iocg, active, active, true, now)
Iocost-->>IocostTimer: skip surplus evaluation
else boost expired
Iocost->>Iocost: surplus evaluation
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Hey - I've found 3 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="block/blk-iocost.c" line_range="2321-2324" />
<code_context>
+ /* skip surplus evaluation if this cgroup is boosted */
+ {
+ struct blkcg_gq *blkg = iocg_to_blkg(iocg);
+ struct ioc_cgrp *iocc = blkcg_to_iocc(blkg->blkcg);
+
+ if (READ_ONCE(iocc->boost_deadline) > now.now_ns) {
+ if (iocg->inuse != iocg->active &&
+ !iocg->abs_vdebt) {
</code_context>
<issue_to_address>
**Parent boosts miss descendant IO**
When a non-root cgroup with active descendants is boosted, `ioc_timer_fn` checks only each active leaf’s own cgroup deadline, so it never applies the parent’s boost to its descendants and their IO shares remain unboosted.
Have timer evaluation apply ancestor boost deadlines to active descendants.
</issue_to_address>
### Comment 2
<location path="block/blk-iocost.c" line_range="3562" />
<code_context>
+ if (duration_us == 0) {
+ WRITE_ONCE(iocc->boost_deadline, 0);
+ } else {
+ u64 deadline = ktime_get_ns() + duration_us * NSEC_PER_USEC;
+
+ WRITE_ONCE(iocc->boost_deadline, deadline);
</code_context>
<issue_to_address>
**Short boosts have no effect**
When the requested duration expires before the next periodic timer evaluation, the write stores only a deadline, and the timer applies the boost only when it observes that deadline; if it misses the interval, the cgroup’s weight is not restored during the boost and the requested share change has no effect.
Apply the boost when it is written or guarantee a timer evaluation before it expires.
Also at `block/blk-iocost.c:2324-2333`, `block/blk-iocost.c:3564`.
</issue_to_address>
### Comment 3
<location path="block/blk-iocost.c" line_range="3590" />
<code_context>
.write = ioc_cost_model_write,
},
+ {
+ .name = "cost.boost",
+ .flags = CFTYPE_NOT_ON_ROOT,
+ .seq_show = ioc_boost_show,
</code_context>
<issue_to_address>
**Boost interface is undocumented**
When operators consult the cgroup-v2 reference for the new file’s behavior, the cgroup-v2 reference documents `io.cost.qos` and `io.cost.model` at lines 1990–2085 but has no `io.cost.boost` entry, so operators cannot find the file’s microsecond input, one-minute limit, or remaining-time output in the kernel interface documentation.
Add an `io.cost.boost` entry to the cgroup-v2 reference describing its duration input, limit, and readback semantics.
</issue_to_address>| struct blkcg_gq *blkg = iocg_to_blkg(iocg); | ||
| struct ioc_cgrp *iocc = blkcg_to_iocc(blkg->blkcg); | ||
|
|
||
| if (READ_ONCE(iocc->boost_deadline) > now.now_ns) { |
There was a problem hiding this comment.
🟠 High · Parent boosts miss descendant IO
When a non-root cgroup with active descendants is boosted, ioc_timer_fn checks only each active leaf’s own cgroup deadline, so it never applies the parent’s boost to its descendants and their IO shares remain unboosted.
Have timer evaluation apply ancestor boost deadlines to active descendants.
Prompt for AI agents
In `block/blk-iocost.c` at lines 2321-2324:
**Parent boosts miss descendant IO**
When a non-root cgroup with active descendants is boosted, `ioc_timer_fn` checks only each active leaf’s own cgroup deadline, so it never applies the parent’s boost to its descendants and their IO shares remain unboosted.
Have timer evaluation apply ancestor boost deadlines to active descendants.| if (duration_us == 0) { | ||
| WRITE_ONCE(iocc->boost_deadline, 0); | ||
| } else { | ||
| u64 deadline = ktime_get_ns() + duration_us * NSEC_PER_USEC; |
There was a problem hiding this comment.
🟡 Medium · Short boosts have no effect
When the requested duration expires before the next periodic timer evaluation, the write stores only a deadline, and the timer applies the boost only when it observes that deadline; if it misses the interval, the cgroup’s weight is not restored during the boost and the requested share change has no effect.
Apply the boost when it is written or guarantee a timer evaluation before it expires.
Also at block/blk-iocost.c:2324-2333, block/blk-iocost.c:3564.
Prompt for AI agents
In `block/blk-iocost.c` at line 3562:
**Short boosts have no effect**
When the requested duration expires before the next periodic timer evaluation, the write stores only a deadline, and the timer applies the boost only when it observes that deadline; if it misses the interval, the cgroup’s weight is not restored during the boost and the requested share change has no effect.
Apply the boost when it is written or guarantee a timer evaluation before it expires.
Also at `block/blk-iocost.c:2324-2333`, `block/blk-iocost.c:3564`.| .write = ioc_cost_model_write, | ||
| }, | ||
| { | ||
| .name = "cost.boost", |
There was a problem hiding this comment.
⚪ Low · Boost interface is undocumented
When operators consult the cgroup-v2 reference for the new file’s behavior, the cgroup-v2 reference documents io.cost.qos and io.cost.model at lines 1990–2085 but has no io.cost.boost entry, so operators cannot find the file’s microsecond input, one-minute limit, or remaining-time output in the kernel interface documentation.
Add an io.cost.boost entry to the cgroup-v2 reference describing its duration input, limit, and readback semantics.
Prompt for AI agents
In `block/blk-iocost.c` at line 3590:
**Boost interface is undocumented**
When operators consult the cgroup-v2 reference for the new file’s behavior, the cgroup-v2 reference documents `io.cost.qos` and `io.cost.model` at lines 1990–2085 but has no `io.cost.boost` entry, so operators cannot find the file’s microsecond input, one-minute limit, or remaining-time output in the kernel interface documentation.
Add an `io.cost.boost` entry to the cgroup-v2 reference describing its duration input, limit, and readback semantics.There was a problem hiding this comment.
🟡 Changes recommended
Concurrency, hierarchy, timer-granularity, and missing ABI documentation issues must be addressed.
4 open findings
What changed in this PR
Adds temporary per-cgroup I/O-cost boosting to preserve full I/O share.
Changes:
- Adds bounded boost duration and remaining-time reporting.
- Skips surplus donation and restores active weight while boosted.
| File | Description |
|---|---|
block/blk-iocost.c |
Implements the io.cost.boost cgroup interface and boost behavior. |
🧠 Review effort: Balanced
Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.
| struct ioc_cgrp { | ||
| struct blkcg_policy_data cpd; | ||
| unsigned int dfl_weight; | ||
| u64 boost_deadline; |
| struct blkcg_gq *blkg = iocg_to_blkg(iocg); | ||
| struct ioc_cgrp *iocc = blkcg_to_iocc(blkg->blkcg); | ||
|
|
||
| if (READ_ONCE(iocc->boost_deadline) > now.now_ns) { |
| u64 deadline = ktime_get_ns() + duration_us * NSEC_PER_USEC; | ||
|
|
||
| WRITE_ONCE(iocc->boost_deadline, deadline); |
| .name = "cost.boost", | ||
| .flags = CFTYPE_NOT_ON_ROOT, | ||
| .seq_show = ioc_boost_show, | ||
| .write = ioc_boost_write, |


Introduce a new per-cgroup file "cost.boost" that allows temporarily boosting an io.cost cgroup. Writing a duration in microseconds to the file enables boost mode for that cgroup. When a cgroup is boosted, iocost skips surplus evaluation for it and restores its inuse weight to active, ensuring the boosted cgroup keeps its full IO share during the boost period.
Summary by Sourcery
Add temporary per-cgroup IO cost boosting through the new
cost.boostinterface.New Features:
cost.boostinterface for temporarily preserving a cgroup’s full IO share for a specified duration.Enhancements: