mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-16 17:57:38 -04:00
blk-cgroup: delay freeing policy data after rcu grace period
Currently blkcg_print_blkgs() must hold RCU to iterate blkgs from a blkcg, and prfill() must hold queue_lock to prevent policy data from being freed by policy deactivation. As a consequence, queue_lock has to be nested under RCU from blkcg_print_blkgs(). Delay freeing policy data until after an RCU grace period so prfill() can be protected by RCU alone. Signed-off-by: Yu Kuai <yukuai@fygo.io> Link: https://patch.msgid.link/e20e5d984b41a026d61851966bed35eb094c4bff.1780621988.git.yukuai@fygo.io Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
@@ -550,13 +550,20 @@ static void bfq_pd_init(struct blkg_policy_data *pd)
|
||||
bfqg->rq_pos_tree = RB_ROOT;
|
||||
}
|
||||
|
||||
static void bfq_pd_free(struct blkg_policy_data *pd)
|
||||
static void bfqg_release(struct rcu_head *rcu)
|
||||
{
|
||||
struct blkg_policy_data *pd =
|
||||
container_of(rcu, struct blkg_policy_data, rcu_head);
|
||||
struct bfq_group *bfqg = pd_to_bfqg(pd);
|
||||
|
||||
bfqg_put(bfqg);
|
||||
}
|
||||
|
||||
static void bfq_pd_free(struct blkg_policy_data *pd)
|
||||
{
|
||||
call_rcu(&pd->rcu_head, bfqg_release);
|
||||
}
|
||||
|
||||
static void bfq_pd_reset_stats(struct blkg_policy_data *pd)
|
||||
{
|
||||
struct bfq_group *bfqg = pd_to_bfqg(pd);
|
||||
|
||||
@@ -140,6 +140,8 @@ struct blkg_policy_data {
|
||||
struct blkcg_gq *blkg;
|
||||
int plid;
|
||||
bool online;
|
||||
|
||||
struct rcu_head rcu_head;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -3050,6 +3050,16 @@ static void ioc_pd_init(struct blkg_policy_data *pd)
|
||||
spin_unlock_irqrestore(&ioc->lock, flags);
|
||||
}
|
||||
|
||||
static void iocg_release(struct rcu_head *rcu)
|
||||
{
|
||||
struct blkg_policy_data *pd =
|
||||
container_of(rcu, struct blkg_policy_data, rcu_head);
|
||||
struct ioc_gq *iocg = pd_to_iocg(pd);
|
||||
|
||||
free_percpu(iocg->pcpu_stat);
|
||||
kfree(iocg);
|
||||
}
|
||||
|
||||
static void ioc_pd_free(struct blkg_policy_data *pd)
|
||||
{
|
||||
struct ioc_gq *iocg = pd_to_iocg(pd);
|
||||
@@ -3074,8 +3084,8 @@ static void ioc_pd_free(struct blkg_policy_data *pd)
|
||||
|
||||
hrtimer_cancel(&iocg->waitq_timer);
|
||||
}
|
||||
free_percpu(iocg->pcpu_stat);
|
||||
kfree(iocg);
|
||||
|
||||
call_rcu(&pd->rcu_head, iocg_release);
|
||||
}
|
||||
|
||||
static void ioc_pd_stat(struct blkg_policy_data *pd, struct seq_file *s)
|
||||
|
||||
@@ -1031,13 +1031,21 @@ static void iolatency_pd_offline(struct blkg_policy_data *pd)
|
||||
iolatency_clear_scaling(blkg);
|
||||
}
|
||||
|
||||
static void iolatency_pd_free(struct blkg_policy_data *pd)
|
||||
static void iolat_release(struct rcu_head *rcu)
|
||||
{
|
||||
struct blkg_policy_data *pd =
|
||||
container_of(rcu, struct blkg_policy_data, rcu_head);
|
||||
struct iolatency_grp *iolat = pd_to_lat(pd);
|
||||
|
||||
free_percpu(iolat->stats);
|
||||
kfree(iolat);
|
||||
}
|
||||
|
||||
static void iolatency_pd_free(struct blkg_policy_data *pd)
|
||||
{
|
||||
call_rcu(&pd->rcu_head, iolat_release);
|
||||
}
|
||||
|
||||
static struct cftype iolatency_files[] = {
|
||||
{
|
||||
.name = "latency",
|
||||
|
||||
@@ -353,14 +353,23 @@ static void throtl_pd_online(struct blkg_policy_data *pd)
|
||||
tg_update_has_rules(tg);
|
||||
}
|
||||
|
||||
static void tg_release(struct rcu_head *rcu)
|
||||
{
|
||||
struct blkg_policy_data *pd =
|
||||
container_of(rcu, struct blkg_policy_data, rcu_head);
|
||||
struct throtl_grp *tg = pd_to_tg(pd);
|
||||
|
||||
blkg_rwstat_exit(&tg->stat_bytes);
|
||||
blkg_rwstat_exit(&tg->stat_ios);
|
||||
kfree(tg);
|
||||
}
|
||||
|
||||
static void throtl_pd_free(struct blkg_policy_data *pd)
|
||||
{
|
||||
struct throtl_grp *tg = pd_to_tg(pd);
|
||||
|
||||
timer_delete_sync(&tg->service_queue.pending_timer);
|
||||
blkg_rwstat_exit(&tg->stat_bytes);
|
||||
blkg_rwstat_exit(&tg->stat_ios);
|
||||
kfree(tg);
|
||||
call_rcu(&pd->rcu_head, tg_release);
|
||||
}
|
||||
|
||||
static struct throtl_grp *
|
||||
|
||||
Reference in New Issue
Block a user