|
Jan Kara |
a1a4ac |
From 4a1254ae1f3f698239bba8ef4c730f5f2fc73ff0 Mon Sep 17 00:00:00 2001
|
|
Jan Kara |
a1a4ac |
From: Jan Kara <jack@suse.cz>
|
|
Jan Kara |
a1a4ac |
Date: Tue, 21 Dec 2021 20:33:16 +0100
|
|
Jan Kara |
a1a4ac |
Subject: [PATCH 3/9] bfq: Split shared queues on move between cgroups
|
|
Jan Kara |
a1a4ac |
References: bsc#1197926
|
|
Jan Kara |
a1a4ac |
Patch-mainline: submitted, in linux-block tree
|
|
Jan Kara |
a1a4ac |
|
|
Jan Kara |
a1a4ac |
When bfqq is shared by multiple processes it can happen that one of the
|
|
Jan Kara |
a1a4ac |
processes gets moved to a different cgroup (or just starts submitting IO
|
|
Jan Kara |
a1a4ac |
for different cgroup). In case that happens we need to split the merged
|
|
Jan Kara |
a1a4ac |
bfqq as otherwise we will have IO for multiple cgroups in one bfqq and
|
|
Jan Kara |
a1a4ac |
we will just account IO time to wrong entities etc.
|
|
Jan Kara |
a1a4ac |
|
|
Jan Kara |
a1a4ac |
Similarly if the bfqq is scheduled to merge with another bfqq but the
|
|
Jan Kara |
a1a4ac |
merge didn't happen yet, cancel the merge as it need not be valid
|
|
Jan Kara |
a1a4ac |
anymore.
|
|
Jan Kara |
a1a4ac |
|
|
Jan Kara |
a1a4ac |
Cc: stable@vger.kernel.org
|
|
Jan Kara |
a1a4ac |
Fixes: e21b7a0b9887 ("block, bfq: add full hierarchical scheduling and cgroups support")
|
|
Jan Kara |
a1a4ac |
Tested-by: "yukuai (C)" <yukuai3@huawei.com>
|
|
Jan Kara |
a1a4ac |
Signed-off-by: Jan Kara <jack@suse.cz>
|
|
Jan Kara |
a1a4ac |
|
|
Jan Kara |
a1a4ac |
---
|
|
Jan Kara |
a1a4ac |
block/bfq-cgroup.c | 36 +++++++++++++++++++++++++++++++++---
|
|
Jan Kara |
a1a4ac |
block/bfq-iosched.c | 2 +-
|
|
Jan Kara |
a1a4ac |
block/bfq-iosched.h | 1 +
|
|
Jan Kara |
a1a4ac |
3 files changed, 35 insertions(+), 4 deletions(-)
|
|
Jan Kara |
a1a4ac |
|
|
Jan Kara |
a1a4ac |
--- a/block/bfq-cgroup.c
|
|
Jan Kara |
a1a4ac |
+++ b/block/bfq-cgroup.c
|
|
Jan Kara |
a1a4ac |
@@ -719,9 +719,39 @@ static struct bfq_group *__bfq_bic_chang
|
|
Jan Kara |
a1a4ac |
}
|
|
Jan Kara |
a1a4ac |
|
|
Jan Kara |
a1a4ac |
if (sync_bfqq) {
|
|
Jan Kara |
a1a4ac |
- entity = &sync_bfqq->entity;
|
|
Jan Kara |
a1a4ac |
- if (entity->sched_data != &bfqg->sched_data)
|
|
Jan Kara |
a1a4ac |
- bfq_bfqq_move(bfqd, sync_bfqq, bfqg);
|
|
Jan Kara |
a1a4ac |
+ if (!sync_bfqq->new_bfqq && !bfq_bfqq_coop(sync_bfqq)) {
|
|
Jan Kara |
a1a4ac |
+ /* We are the only user of this bfqq, just move it */
|
|
Jan Kara |
a1a4ac |
+ if (sync_bfqq->entity.sched_data != &bfqg->sched_data)
|
|
Jan Kara |
a1a4ac |
+ bfq_bfqq_move(bfqd, sync_bfqq, bfqg);
|
|
Jan Kara |
a1a4ac |
+ } else {
|
|
Jan Kara |
a1a4ac |
+ struct bfq_queue *bfqq;
|
|
Jan Kara |
a1a4ac |
+
|
|
Jan Kara |
a1a4ac |
+ /*
|
|
Jan Kara |
a1a4ac |
+ * The queue was merged to a different queue. Check
|
|
Jan Kara |
a1a4ac |
+ * that the merge chain still belongs to the same
|
|
Jan Kara |
a1a4ac |
+ * cgroup.
|
|
Jan Kara |
a1a4ac |
+ */
|
|
Jan Kara |
a1a4ac |
+ for (bfqq = sync_bfqq; bfqq; bfqq = bfqq->new_bfqq)
|
|
Jan Kara |
a1a4ac |
+ if (bfqq->entity.sched_data !=
|
|
Jan Kara |
a1a4ac |
+ &bfqg->sched_data)
|
|
Jan Kara |
a1a4ac |
+ break;
|
|
Jan Kara |
a1a4ac |
+ if (bfqq) {
|
|
Jan Kara |
a1a4ac |
+ /*
|
|
Jan Kara |
a1a4ac |
+ * Some queue changed cgroup so the merge is
|
|
Jan Kara |
a1a4ac |
+ * not valid anymore. We cannot easily just
|
|
Jan Kara |
a1a4ac |
+ * cancel the merge (by clearing new_bfqq) as
|
|
Jan Kara |
a1a4ac |
+ * there may be other processes using this
|
|
Jan Kara |
a1a4ac |
+ * queue and holding refs to all queues below
|
|
Jan Kara |
a1a4ac |
+ * sync_bfqq->new_bfqq. Similarly if the merge
|
|
Jan Kara |
a1a4ac |
+ * already happened, we need to detach from
|
|
Jan Kara |
a1a4ac |
+ * bfqq now so that we cannot merge bio to a
|
|
Jan Kara |
a1a4ac |
+ * request from the old cgroup.
|
|
Jan Kara |
a1a4ac |
+ */
|
|
Jan Kara |
a1a4ac |
+ bfq_put_cooperator(sync_bfqq);
|
|
Jan Kara |
a1a4ac |
+ bfq_release_process_ref(bfqd, sync_bfqq);
|
|
Jan Kara |
a1a4ac |
+ bic_set_bfqq(bic, NULL, 1);
|
|
Jan Kara |
a1a4ac |
+ }
|
|
Jan Kara |
a1a4ac |
+ }
|
|
Jan Kara |
a1a4ac |
}
|
|
Jan Kara |
a1a4ac |
|
|
Jan Kara |
a1a4ac |
return bfqg;
|
|
Jan Kara |
a1a4ac |
--- a/block/bfq-iosched.c
|
|
Jan Kara |
a1a4ac |
+++ b/block/bfq-iosched.c
|
|
Jan Kara |
a1a4ac |
@@ -5030,7 +5030,7 @@ void bfq_put_queue(struct bfq_queue *bfq
|
|
Jan Kara |
a1a4ac |
#endif
|
|
Jan Kara |
a1a4ac |
}
|
|
Jan Kara |
a1a4ac |
|
|
Jan Kara |
a1a4ac |
-static void bfq_put_cooperator(struct bfq_queue *bfqq)
|
|
Jan Kara |
a1a4ac |
+void bfq_put_cooperator(struct bfq_queue *bfqq)
|
|
Jan Kara |
a1a4ac |
{
|
|
Jan Kara |
a1a4ac |
struct bfq_queue *__bfqq, *next;
|
|
Jan Kara |
a1a4ac |
|
|
Jan Kara |
a1a4ac |
--- a/block/bfq-iosched.h
|
|
Jan Kara |
a1a4ac |
+++ b/block/bfq-iosched.h
|
|
Jan Kara |
a1a4ac |
@@ -955,6 +955,7 @@ void bfq_weights_tree_remove(struct bfq_
|
|
Jan Kara |
a1a4ac |
void bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
|
Jan Kara |
a1a4ac |
bool compensate, enum bfqq_expiration reason);
|
|
Jan Kara |
a1a4ac |
void bfq_put_queue(struct bfq_queue *bfqq);
|
|
Jan Kara |
a1a4ac |
+void bfq_put_cooperator(struct bfq_queue *bfqq);
|
|
Jan Kara |
a1a4ac |
void bfq_end_wr_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg);
|
|
Jan Kara |
a1a4ac |
void bfq_release_process_ref(struct bfq_data *bfqd, struct bfq_queue *bfqq);
|
|
Jan Kara |
a1a4ac |
void bfq_schedule_dispatch(struct bfq_data *bfqd);
|