Skip to content

Commit d7bd15a

Browse files
htejunaxboe
authored andcommitted
iocost: over-budget forced IOs should schedule async delay
When over-budget IOs are force-issued through root cgroup, iocg_kick_delay() adjusts the async delay accordingly but doesn't actually schedule async throttle for the issuing task. This bug is pretty well masked because sooner or later the offending threads are gonna get directly throttled on regular IOs or have async delay scheduled by mem_cgroup_throttle_swaprate(). However, it can affect control quality on filesystem metadata heavy operations. Let's fix it by invoking blkcg_schedule_throttle() when iocg_kick_delay() says async delay is needed. Signed-off-by: Tejun Heo <[email protected]> Fixes: 7caa471 ("blkcg: implement blk-iocost") Cc: [email protected] Reported-by: Josef Bacik <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 6afa873 commit d7bd15a

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

block/blk-iocost.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ static enum hrtimer_restart iocg_waitq_timer_fn(struct hrtimer *timer)
12121212
return HRTIMER_NORESTART;
12131213
}
12141214

1215-
static void iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now, u64 cost)
1215+
static bool iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now, u64 cost)
12161216
{
12171217
struct ioc *ioc = iocg->ioc;
12181218
struct blkcg_gq *blkg = iocg_to_blkg(iocg);
@@ -1229,11 +1229,11 @@ static void iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now, u64 cost)
12291229
/* clear or maintain depending on the overage */
12301230
if (time_before_eq64(vtime, now->vnow)) {
12311231
blkcg_clear_delay(blkg);
1232-
return;
1232+
return false;
12331233
}
12341234
if (!atomic_read(&blkg->use_delay) &&
12351235
time_before_eq64(vtime, now->vnow + vmargin))
1236-
return;
1236+
return false;
12371237

12381238
/* use delay */
12391239
if (cost) {
@@ -1250,10 +1250,11 @@ static void iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now, u64 cost)
12501250
oexpires = ktime_to_ns(hrtimer_get_softexpires(&iocg->delay_timer));
12511251
if (hrtimer_is_queued(&iocg->delay_timer) &&
12521252
abs(oexpires - expires) <= margin_ns / 4)
1253-
return;
1253+
return true;
12541254

12551255
hrtimer_start_range_ns(&iocg->delay_timer, ns_to_ktime(expires),
12561256
margin_ns / 4, HRTIMER_MODE_ABS);
1257+
return true;
12571258
}
12581259

12591260
static enum hrtimer_restart iocg_delay_timer_fn(struct hrtimer *timer)
@@ -1739,7 +1740,9 @@ static void ioc_rqos_throttle(struct rq_qos *rqos, struct bio *bio)
17391740
*/
17401741
if (bio_issue_as_root_blkg(bio) || fatal_signal_pending(current)) {
17411742
atomic64_add(abs_cost, &iocg->abs_vdebt);
1742-
iocg_kick_delay(iocg, &now, cost);
1743+
if (iocg_kick_delay(iocg, &now, cost))
1744+
blkcg_schedule_throttle(rqos->q,
1745+
(bio->bi_opf & REQ_SWAP) == REQ_SWAP);
17431746
return;
17441747
}
17451748

0 commit comments

Comments
 (0)