FAILED: patch "[PATCH] bfq: Get rid of __bio_blkcg() usage" failed to apply to 5.10-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 4e54a2493e582361adc3bfbf06c7d50d19d18837 Mon Sep 17 00:00:00 2001
From: Jan Kara <[email protected]>
Date: Fri, 1 Apr 2022 12:27:49 +0200
Subject: [PATCH] bfq: Get rid of __bio_blkcg() usage
BFQ usage of __bio_blkcg() is a relict from the past. Furthermore if bio would not be associated with any blkcg, the usage of __bio_blkcg() in BFQ is prone to races with the task being migrated between cgroups as __bio_blkcg() calls at different places could return different blkcgs.
Convert BFQ to the new situation where bio->bi_blkg is initialized in bio_set_dev() and thus practically always valid. This allows us to save blkcg_gq lookup and noticeably simplify the code.
block/bfq-cgroup.c +23 -40
@@ -586,27 +586,11 @@ static void bfq_group_set_parent(struct bfq_group *bfqg, entity->sched_data = &parent->sched_data; } -static struct bfq_group *bfq_lookup_bfqg (struct bfq_data *bfqd, -struct blkcg *blkcg) +static void bfq_link_bfqg (struct bfq_data *bfqd,struct bfq_group *bfqg) { -struct blkcg_gq *blkg; - - blkg =blkg_lookup (blkcg, bfqd->queue); -if (likely (blkg)) -return blkg_to_bfqg (blkg); -return NULL ; -} - -struct bfq_group *bfq_find_set_group (struct bfq_data *bfqd, -struct blkcg *blkcg) -{ -struct bfq_group *bfqg, *parent; +struct bfq_group *parent;struct bfq_entity *entity; - bfqg =bfq_lookup_bfqg (bfqd, blkcg); -if (unlikely (!bfqg)) -return NULL ; -/* * Update chain of bfq_groups as we might be handling a leaf group * which, along with some of its relatives, has not been hooked yet
@@ -623,8 +607,15 @@ struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd,bfq_group_set_parent (curr_bfqg, parent); } } +} -return bfqg; +struct bfq_group *bfq_bio_bfqg (struct bfq_data *bfqd,struct bio *bio) +{ +struct blkcg_gq *blkg = bio->bi_blkg; + +if (!blkg) +return bfqd->root_group; +return blkg_to_bfqg (blkg); }/**
@@ -714,25 +705,15 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,* Move bic to blkcg, assuming that bfqd->lock is held; which makes * sure that the reference to cgroup is valid across the call (see * comments in bfq_bic_update_cgroup on this issue) -* -* NOTE: an alternative approach might have been to store the current -* cgroup in bfqq and getting a reference to it, reducing the lookup -* time here, at the price of slightly more complex code. */ -static struct bfq_group *__bfq_bic_change_cgroup (struct bfq_data *bfqd, -struct bfq_io_cq *bic, -struct blkcg *blkcg) +static void *__bfq_bic_change_cgroup (struct bfq_data *bfqd, +struct bfq_io_cq *bic, +struct bfq_group *bfqg) {struct bfq_queue *async_bfqq =bic_to_bfqq (bic,0 );struct bfq_queue *sync_bfqq =bic_to_bfqq (bic,1 ); -struct bfq_group *bfqg;struct bfq_entity *entity; - bfqg =bfq_find_set_group (bfqd, blkcg); - -if (unlikely (!bfqg)) - bfqg = bfqd->root_group; -if (async_bfqq) { entity = &async_bfqq->entity;
@@ -784,20 +765,24 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd,void bfq_bic_update_cgroup (struct bfq_io_cq *bic,struct bio *bio) {struct bfq_data *bfqd =bic_to_bfqd (bic); -struct bfq_group *bfqg =NULL ; +struct bfq_group *bfqg =bfq_bio_bfqg (bfqd, bio);uint64_t serial_nr; -rcu_read_lock (); - serial_nr =__bio_blkcg (bio)->css.serial_nr; + serial_nr =bfqg_to_blkg (bfqg)->blkcg->css.serial_nr;/* * Check whether blkcg has changed. The condition may trigger * spuriously on a newly created cic but there's no harm. */ if (unlikely (!bfqd) ||likely (bic->blkcg_serial_nr == serial_nr)) - goto out; +return ; - bfqg =__bfq_bic_change_cgroup (bfqd, bic,__bio_blkcg (bio)); +/* +* New cgroup for this process. Make sure it is linked to bfq internal +* cgroup hierarchy. +*/ +bfq_link_bfqg (bfqd, bfqg); +__bfq_bic_change_cgroup (bfqd, bic, bfqg);/* * Update blkg_path for bfq_log_* functions. We cache this * path, and update it here, for the following
@@ -850,8 +835,6 @@ void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)*/ blkg_path (bfqg_to_blkg (bfqg), bfqg->blkg_path,sizeof (bfqg->blkg_path)); bic->blkcg_serial_nr = serial_nr; -out: -rcu_read_unlock (); }/**
@@ -1469,7 +1452,7 @@ void bfq_end_wr_async(struct bfq_data *bfqd)bfq_end_wr_async_queues (bfqd, bfqd->root_group); } -struct bfq_group *bfq_find_set_group (struct bfq_data *bfqd,struct blkcg *blkcg) +struct bfq_group *bfq_bio_bfqg (struct bfq_data *bfqd,struct bio *bio) {return bfqd->root_group; }
block/bfq-iosched.c +1 -10
@@ -5726,14 +5726,7 @@ static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,struct bfq_queue *bfqq;struct bfq_group *bfqg; -rcu_read_lock (); - - bfqg =bfq_find_set_group (bfqd,__bio_blkcg (bio)); -if (!bfqg) { - bfqq = &bfqd->oom_bfqq; - goto out; - } - + bfqg =bfq_bio_bfqg (bfqd, bio);if (!is_sync) { async_bfqq =bfq_async_queue_prio (bfqd, bfqg, ioprio_class, ioprio);
@@ -5779,8 +5772,6 @@ static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,if (bfqq != &bfqd->oom_bfqq && is_sync && !respawn) bfqq =bfq_do_or_sched_stable_merge (bfqd, bfqq, bic); - -rcu_read_unlock ();return bfqq; }
block/bfq-iosched.h +1 -2
@@ -1009,8 +1009,7 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,void bfq_init_entity (struct bfq_entity *entity,struct bfq_group *bfqg);void bfq_bic_update_cgroup (struct bfq_io_cq *bic,struct bio *bio);void bfq_end_wr_async (struct bfq_data *bfqd); -struct bfq_group *bfq_find_set_group (struct bfq_data *bfqd, -struct blkcg *blkcg); +struct bfq_group *bfq_bio_bfqg (struct bfq_data *bfqd,struct bio *bio);struct blkcg_gq *bfqg_to_blkg (struct bfq_group *bfqg);struct bfq_group *bfqq_group (struct bfq_queue *bfqq);struct bfq_group *bfq_create_group_hierarchy (struct bfq_data *bfqd,int node);