Skip to content

Commit 09df6a7

Browse files
jankaraaxboe
authored andcommitted
bfq: Fix warning in bfqq_request_over_limit()
People are occasionally reporting a warning bfqq_request_over_limit() triggering reporting that BFQ's idea of cgroup hierarchy (and its depth) does not match what generic blkcg code thinks. This can actually happen when bfqq gets moved between BFQ groups while bfqq_request_over_limit() is running. Make sure the code is safe against BFQ queue being moved to a different BFQ group. Fixes: 76f1df8 ("bfq: Limit number of requests consumed by each cgroup") CC: stable@vger.kernel.org Link: https://lore.kernel.org/all/CAJCQCtTw_2C7ZSz7as5Gvq=OmnDiio=HRkQekqWpKot84sQhFA@mail.gmail.com/ Reported-by: Chris Murphy <lists@colorremedies.com> Reported-by: "yukuai (C)" <yukuai3@huawei.com> Signed-off-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/r/20220407140738.9723-1-jack@suse.cz Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 4cddeac commit 09df6a7

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

block/bfq-iosched.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit)
569569
struct bfq_entity *entity = &bfqq->entity;
570570
struct bfq_entity *inline_entities[BFQ_LIMIT_INLINE_DEPTH];
571571
struct bfq_entity **entities = inline_entities;
572-
int depth, level;
572+
int depth, level, alloc_depth = BFQ_LIMIT_INLINE_DEPTH;
573573
int class_idx = bfqq->ioprio_class - 1;
574574
struct bfq_sched_data *sched_data;
575575
unsigned long wsum;
@@ -578,15 +578,21 @@ static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit)
578578
if (!entity->on_st_or_in_serv)
579579
return false;
580580

581+
retry:
582+
spin_lock_irq(&bfqd->lock);
581583
/* +1 for bfqq entity, root cgroup not included */
582584
depth = bfqg_to_blkg(bfqq_group(bfqq))->blkcg->css.cgroup->level + 1;
583-
if (depth > BFQ_LIMIT_INLINE_DEPTH) {
585+
if (depth > alloc_depth) {
586+
spin_unlock_irq(&bfqd->lock);
587+
if (entities != inline_entities)
588+
kfree(entities);
584589
entities = kmalloc_array(depth, sizeof(*entities), GFP_NOIO);
585590
if (!entities)
586591
return false;
592+
alloc_depth = depth;
593+
goto retry;
587594
}
588595

589-
spin_lock_irq(&bfqd->lock);
590596
sched_data = entity->sched_data;
591597
/* Gather our ancestors as we need to traverse them in reverse order */
592598
level = 0;

0 commit comments

Comments
 (0)