| From 6ee39a7dd280cf282441c6a82189730fbf053454 Mon Sep 17 00:00:00 2001 |
| From: Paolo Valente <paolo.valente@linaro.org> |
| Date: Sat, 21 Mar 2020 10:45:21 +0100 |
| Subject: [PATCH] block, bfq: invoke flush_idle_tree after |
| reparent_active_queues in pd_offline |
| |
| commit 4d38a87fbb77fb9ff2ff4e914162a8ae6453eff5 upstream. |
| |
| In bfq_pd_offline(), the function bfq_flush_idle_tree() is invoked to |
| flush the rb tree that contains all idle entities belonging to the pd |
| (cgroup) being destroyed. In particular, bfq_flush_idle_tree() is |
| invoked before bfq_reparent_active_queues(). Yet the latter may happen |
| to add some entities to the idle tree. It happens if, in some of the |
| calls to bfq_bfqq_move() performed by bfq_reparent_active_queues(), |
| the queue to move is empty and gets expired. |
| |
| This commit simply reverses the invocation order between |
| bfq_flush_idle_tree() and bfq_reparent_active_queues(). |
| |
| Tested-by: cki-project@redhat.com |
| Signed-off-by: Paolo Valente <paolo.valente@linaro.org> |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c |
| index 6df4cb195ed4..52c2ab6c9d14 100644 |
| --- a/block/bfq-cgroup.c |
| +++ b/block/bfq-cgroup.c |
| @@ -800,13 +800,6 @@ static void bfq_pd_offline(struct blkg_policy_data *pd) |
| st = bfqg->sched_data.service_tree + i; |
| |
| /* |
| - * The idle tree may still contain bfq_queues belonging |
| - * to exited task because they never migrated to a different |
| - * cgroup from the one being destroyed now. |
| - */ |
| - bfq_flush_idle_tree(st); |
| - |
| - /* |
| * It may happen that some queues are still active |
| * (busy) upon group destruction (if the corresponding |
| * processes have been forced to terminate). We move |
| @@ -819,6 +812,19 @@ static void bfq_pd_offline(struct blkg_policy_data *pd) |
| * scheduler has taken no reference. |
| */ |
| bfq_reparent_active_queues(bfqd, bfqg, st, i); |
| + |
| + /* |
| + * The idle tree may still contain bfq_queues |
| + * belonging to exited task because they never |
| + * migrated to a different cgroup from the one being |
| + * destroyed now. In addition, even |
| + * bfq_reparent_active_queues() may happen to add some |
| + * entities to the idle tree. It happens if, in some |
| + * of the calls to bfq_bfqq_move() performed by |
| + * bfq_reparent_active_queues(), the queue to move is |
| + * empty and gets expired. |
| + */ |
| + bfq_flush_idle_tree(st); |
| } |
| |
| __bfq_deactivate_entity(entity, false); |
| -- |
| 2.7.4 |
| |