Commit 4d38a87f authored by Paolo Valente's avatar Paolo Valente Committed by Jens Axboe
Browse files

block, bfq: invoke flush_idle_tree after reparent_active_queues in pd_offline



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: default avatar <cki-project@redhat.com>
Signed-off-by: default avatarPaolo Valente <paolo.valente@linaro.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 576682fa
Loading
Loading
Loading
Loading
+13 −7
Original line number Diff line number Diff line
@@ -893,13 +893,6 @@ static void bfq_pd_offline(struct blkg_policy_data *pd)
	for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) {
		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
@@ -913,6 +906,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);