|
Jan Kara |
996a1f |
From cb5e5543e67afb6ee9670075531107884021da3f Mon Sep 17 00:00:00 2001
|
|
Jan Kara |
996a1f |
From: Jan Kara <jack@suse.cz>
|
|
Jan Kara |
996a1f |
Date: Fri, 4 Mar 2022 18:57:35 +0100
|
|
Jan Kara |
996a1f |
Subject: [PATCH 8/9] bfq: Get rid of __bio_blkcg() usage
|
|
Jan Kara |
996a1f |
References: bsc#1197926
|
|
Jan Kara |
996a1f |
Patch-mainline: submitted, in linux-block tree
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
BFQ usage of __bio_blkcg() is a relict from the past. Furthermore if bio
|
|
Jan Kara |
996a1f |
would not be associated with any blkcg, the usage of __bio_blkcg() in
|
|
Jan Kara |
996a1f |
BFQ is prone to races with the task being migrated between cgroups as
|
|
Jan Kara |
996a1f |
__bio_blkcg() calls at different places could return different blkcgs.
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
Convert BFQ to the new situation where bio->bi_blkg is initialized in
|
|
Jan Kara |
996a1f |
bio_set_dev() and thus practically always valid. This allows us to save
|
|
Jan Kara |
996a1f |
blkcg_gq lookup and noticeably simplify the code.
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
Cc: stable@vger.kernel.org
|
|
Jan Kara |
996a1f |
Fixes: 0fe061b9f03c ("blkcg: fix ref count issue with bio_blkcg() using task_css")
|
|
Jan Kara |
996a1f |
Tested-by: "yukuai (C)" <yukuai3@huawei.com>
|
|
Jan Kara |
996a1f |
Signed-off-by: Jan Kara <jack@suse.cz>
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
---
|
|
Jan Kara |
996a1f |
block/bfq-cgroup.c | 63 ++++++++++++++++++----------------------------------
|
|
Jan Kara |
996a1f |
block/bfq-iosched.c | 10 --------
|
|
Jan Kara |
996a1f |
block/bfq-iosched.h | 3 --
|
|
Jan Kara |
996a1f |
3 files changed, 25 insertions(+), 51 deletions(-)
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
--- a/block/bfq-cgroup.c
|
|
Jan Kara |
996a1f |
+++ b/block/bfq-cgroup.c
|
|
Jan Kara |
996a1f |
@@ -582,27 +582,11 @@ static void bfq_group_set_parent(struct
|
|
Jan Kara |
996a1f |
entity->sched_data = &parent->sched_data;
|
|
Jan Kara |
996a1f |
}
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
-static struct bfq_group *bfq_lookup_bfqg(struct bfq_data *bfqd,
|
|
Jan Kara |
996a1f |
- struct blkcg *blkcg)
|
|
Jan Kara |
996a1f |
+static void bfq_link_bfqg(struct bfq_data *bfqd, struct bfq_group *bfqg)
|
|
Jan Kara |
996a1f |
{
|
|
Jan Kara |
996a1f |
- struct blkcg_gq *blkg;
|
|
Jan Kara |
996a1f |
-
|
|
Jan Kara |
996a1f |
- blkg = blkg_lookup(blkcg, bfqd->queue);
|
|
Jan Kara |
996a1f |
- if (likely(blkg))
|
|
Jan Kara |
996a1f |
- return blkg_to_bfqg(blkg);
|
|
Jan Kara |
996a1f |
- return NULL;
|
|
Jan Kara |
996a1f |
-}
|
|
Jan Kara |
996a1f |
-
|
|
Jan Kara |
996a1f |
-struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd,
|
|
Jan Kara |
996a1f |
- struct blkcg *blkcg)
|
|
Jan Kara |
996a1f |
-{
|
|
Jan Kara |
996a1f |
- struct bfq_group *bfqg, *parent;
|
|
Jan Kara |
996a1f |
+ struct bfq_group *parent;
|
|
Jan Kara |
996a1f |
struct bfq_entity *entity;
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
- bfqg = bfq_lookup_bfqg(bfqd, blkcg);
|
|
Jan Kara |
996a1f |
- if (unlikely(!bfqg))
|
|
Jan Kara |
996a1f |
- return NULL;
|
|
Jan Kara |
996a1f |
-
|
|
Jan Kara |
996a1f |
/*
|
|
Jan Kara |
996a1f |
* Update chain of bfq_groups as we might be handling a leaf group
|
|
Jan Kara |
996a1f |
* which, along with some of its relatives, has not been hooked yet
|
|
Jan Kara |
996a1f |
@@ -619,8 +603,15 @@ struct bfq_group *bfq_find_set_group(str
|
|
Jan Kara |
996a1f |
bfq_group_set_parent(curr_bfqg, parent);
|
|
Jan Kara |
996a1f |
}
|
|
Jan Kara |
996a1f |
}
|
|
Jan Kara |
996a1f |
+}
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
- return bfqg;
|
|
Jan Kara |
996a1f |
+struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio)
|
|
Jan Kara |
996a1f |
+{
|
|
Jan Kara |
996a1f |
+ struct blkcg_gq *blkg = bio->bi_blkg;
|
|
Jan Kara |
996a1f |
+
|
|
Jan Kara |
996a1f |
+ if (!blkg)
|
|
Jan Kara |
996a1f |
+ return bfqd->root_group;
|
|
Jan Kara |
996a1f |
+ return blkg_to_bfqg(blkg);
|
|
Jan Kara |
996a1f |
}
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
/**
|
|
Jan Kara |
996a1f |
@@ -690,25 +681,15 @@ void bfq_bfqq_move(struct bfq_data *bfqd
|
|
Jan Kara |
996a1f |
* Move bic to blkcg, assuming that bfqd->lock is held; which makes
|
|
Jan Kara |
996a1f |
* sure that the reference to cgroup is valid across the call (see
|
|
Jan Kara |
996a1f |
* comments in bfq_bic_update_cgroup on this issue)
|
|
Jan Kara |
996a1f |
- *
|
|
Jan Kara |
996a1f |
- * NOTE: an alternative approach might have been to store the current
|
|
Jan Kara |
996a1f |
- * cgroup in bfqq and getting a reference to it, reducing the lookup
|
|
Jan Kara |
996a1f |
- * time here, at the price of slightly more complex code.
|
|
Jan Kara |
996a1f |
*/
|
|
Jan Kara |
996a1f |
-static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
|
|
Jan Kara |
996a1f |
- struct bfq_io_cq *bic,
|
|
Jan Kara |
996a1f |
- struct blkcg *blkcg)
|
|
Jan Kara |
996a1f |
+static void *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
|
|
Jan Kara |
996a1f |
+ struct bfq_io_cq *bic,
|
|
Jan Kara |
996a1f |
+ struct bfq_group *bfqg)
|
|
Jan Kara |
996a1f |
{
|
|
Jan Kara |
996a1f |
struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0);
|
|
Jan Kara |
996a1f |
struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1);
|
|
Jan Kara |
996a1f |
- struct bfq_group *bfqg;
|
|
Jan Kara |
996a1f |
struct bfq_entity *entity;
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
- bfqg = bfq_find_set_group(bfqd, blkcg);
|
|
Jan Kara |
996a1f |
-
|
|
Jan Kara |
996a1f |
- if (unlikely(!bfqg))
|
|
Jan Kara |
996a1f |
- bfqg = bfqd->root_group;
|
|
Jan Kara |
996a1f |
-
|
|
Jan Kara |
996a1f |
if (async_bfqq) {
|
|
Jan Kara |
996a1f |
entity = &async_bfqq->entity;
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
@@ -760,20 +741,24 @@ static struct bfq_group *__bfq_bic_chang
|
|
Jan Kara |
996a1f |
void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
|
|
Jan Kara |
996a1f |
{
|
|
Jan Kara |
996a1f |
struct bfq_data *bfqd = bic_to_bfqd(bic);
|
|
Jan Kara |
996a1f |
- struct bfq_group *bfqg = NULL;
|
|
Jan Kara |
996a1f |
+ struct bfq_group *bfqg = bfq_bio_bfqg(bfqd, bio);
|
|
Jan Kara |
996a1f |
uint64_t serial_nr;
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
- rcu_read_lock();
|
|
Jan Kara |
996a1f |
- serial_nr = __bio_blkcg(bio)->css.serial_nr;
|
|
Jan Kara |
996a1f |
+ serial_nr = bfqg_to_blkg(bfqg)->blkcg->css.serial_nr;
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
/*
|
|
Jan Kara |
996a1f |
* Check whether blkcg has changed. The condition may trigger
|
|
Jan Kara |
996a1f |
* spuriously on a newly created cic but there's no harm.
|
|
Jan Kara |
996a1f |
*/
|
|
Jan Kara |
996a1f |
if (unlikely(!bfqd) || likely(bic->blkcg_serial_nr == serial_nr))
|
|
Jan Kara |
996a1f |
- goto out;
|
|
Jan Kara |
996a1f |
+ return;
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
- bfqg = __bfq_bic_change_cgroup(bfqd, bic, __bio_blkcg(bio));
|
|
Jan Kara |
996a1f |
+ /*
|
|
Jan Kara |
996a1f |
+ * New cgroup for this process. Make sure it is linked to bfq internal
|
|
Jan Kara |
996a1f |
+ * cgroup hierarchy.
|
|
Jan Kara |
996a1f |
+ */
|
|
Jan Kara |
996a1f |
+ bfq_link_bfqg(bfqd, bfqg);
|
|
Jan Kara |
996a1f |
+ __bfq_bic_change_cgroup(bfqd, bic, bfqg);
|
|
Jan Kara |
996a1f |
/*
|
|
Jan Kara |
996a1f |
* Update blkg_path for bfq_log_* functions. We cache this
|
|
Jan Kara |
996a1f |
* path, and update it here, for the following
|
|
Jan Kara |
996a1f |
@@ -826,8 +811,6 @@ void bfq_bic_update_cgroup(struct bfq_io
|
|
Jan Kara |
996a1f |
*/
|
|
Jan Kara |
996a1f |
blkg_path(bfqg_to_blkg(bfqg), bfqg->blkg_path, sizeof(bfqg->blkg_path));
|
|
Jan Kara |
996a1f |
bic->blkcg_serial_nr = serial_nr;
|
|
Jan Kara |
996a1f |
-out:
|
|
Jan Kara |
996a1f |
- rcu_read_unlock();
|
|
Jan Kara |
996a1f |
}
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
/**
|
|
Jan Kara |
996a1f |
@@ -1445,7 +1428,7 @@ void bfq_end_wr_async(struct bfq_data *b
|
|
Jan Kara |
996a1f |
bfq_end_wr_async_queues(bfqd, bfqd->root_group);
|
|
Jan Kara |
996a1f |
}
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
-struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd, struct blkcg *blkcg)
|
|
Jan Kara |
996a1f |
+struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio)
|
|
Jan Kara |
996a1f |
{
|
|
Jan Kara |
996a1f |
return bfqd->root_group;
|
|
Jan Kara |
996a1f |
}
|
|
Jan Kara |
996a1f |
--- a/block/bfq-iosched.c
|
|
Jan Kara |
996a1f |
+++ b/block/bfq-iosched.c
|
|
Jan Kara |
996a1f |
@@ -5267,14 +5267,7 @@ static struct bfq_queue *bfq_get_queue(s
|
|
Jan Kara |
996a1f |
struct bfq_queue *bfqq;
|
|
Jan Kara |
996a1f |
struct bfq_group *bfqg;
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
- rcu_read_lock();
|
|
Jan Kara |
996a1f |
-
|
|
Jan Kara |
996a1f |
- bfqg = bfq_find_set_group(bfqd, __bio_blkcg(bio));
|
|
Jan Kara |
996a1f |
- if (!bfqg) {
|
|
Jan Kara |
996a1f |
- bfqq = &bfqd->oom_bfqq;
|
|
Jan Kara |
996a1f |
- goto out;
|
|
Jan Kara |
996a1f |
- }
|
|
Jan Kara |
996a1f |
-
|
|
Jan Kara |
996a1f |
+ bfqg = bfq_bio_bfqg(bfqd, bio);
|
|
Jan Kara |
996a1f |
if (!is_sync) {
|
|
Jan Kara |
996a1f |
async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class,
|
|
Jan Kara |
996a1f |
ioprio);
|
|
Jan Kara |
996a1f |
@@ -5318,7 +5311,6 @@ static struct bfq_queue *bfq_get_queue(s
|
|
Jan Kara |
996a1f |
out:
|
|
Jan Kara |
996a1f |
bfqq->ref++; /* get a process reference to this queue */
|
|
Jan Kara |
996a1f |
bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, bfqq->ref);
|
|
Jan Kara |
996a1f |
- rcu_read_unlock();
|
|
Jan Kara |
996a1f |
return bfqq;
|
|
Jan Kara |
996a1f |
}
|
|
Jan Kara |
996a1f |
|
|
Jan Kara |
996a1f |
--- a/block/bfq-iosched.h
|
|
Jan Kara |
996a1f |
+++ b/block/bfq-iosched.h
|
|
Jan Kara |
996a1f |
@@ -985,8 +985,7 @@ void bfq_bfqq_move(struct bfq_data *bfqd
|
|
Jan Kara |
996a1f |
void bfq_init_entity(struct bfq_entity *entity, struct bfq_group *bfqg);
|
|
Jan Kara |
996a1f |
void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio);
|
|
Jan Kara |
996a1f |
void bfq_end_wr_async(struct bfq_data *bfqd);
|
|
Jan Kara |
996a1f |
-struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd,
|
|
Jan Kara |
996a1f |
- struct blkcg *blkcg);
|
|
Jan Kara |
996a1f |
+struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio);
|
|
Jan Kara |
996a1f |
struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg);
|
|
Jan Kara |
996a1f |
struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
|
|
Jan Kara |
996a1f |
struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node);
|