mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-30 23:54:04 +08:00
block: fix q->blkg_list corruption during disk rebind
[ Upstream commit8b8ace0803
] Multiple gendisk instances can allocated/added for single request queue in case of disk rebind. blkg may still stay in q->blkg_list when calling blkcg_init_disk() for rebind, then q->blkg_list becomes corrupted. Fix the list corruption issue by: - add blkg_init_queue() to initialize q->blkg_list & q->blkcg_mutex only - move calling blkg_init_queue() into blk_alloc_queue() The list corruption should be started since commitf1c006f1c6
("blk-cgroup: synchronize pd_free_fn() from blkg_free_workfn() and blkcg_deactivate_policy()") which delays removing blkg from q->blkg_list into blkg_free_workfn(). Fixes:f1c006f1c6
("blk-cgroup: synchronize pd_free_fn() from blkg_free_workfn() and blkcg_deactivate_policy()") Fixes:1059699f87
("block: move blkcg initialization/destroy into disk allocation/release handler") Cc: Yu Kuai <yukuai3@huawei.com> Cc: Tejun Heo <tj@kernel.org> Signed-off-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Yu Kuai <yukuai3@huawei.com> Link: https://lore.kernel.org/r/20240407125910.4053377-1-ming.lei@redhat.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
7af5582ea6
commit
740ffad95c
@ -1409,6 +1409,12 @@ static int blkcg_css_online(struct cgroup_subsys_state *css)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void blkg_init_queue(struct request_queue *q)
|
||||||
|
{
|
||||||
|
INIT_LIST_HEAD(&q->blkg_list);
|
||||||
|
mutex_init(&q->blkcg_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
int blkcg_init_disk(struct gendisk *disk)
|
int blkcg_init_disk(struct gendisk *disk)
|
||||||
{
|
{
|
||||||
struct request_queue *q = disk->queue;
|
struct request_queue *q = disk->queue;
|
||||||
@ -1416,9 +1422,6 @@ int blkcg_init_disk(struct gendisk *disk)
|
|||||||
bool preloaded;
|
bool preloaded;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&q->blkg_list);
|
|
||||||
mutex_init(&q->blkcg_mutex);
|
|
||||||
|
|
||||||
new_blkg = blkg_alloc(&blkcg_root, disk, GFP_KERNEL);
|
new_blkg = blkg_alloc(&blkcg_root, disk, GFP_KERNEL);
|
||||||
if (!new_blkg)
|
if (!new_blkg)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -188,6 +188,7 @@ struct blkcg_policy {
|
|||||||
extern struct blkcg blkcg_root;
|
extern struct blkcg blkcg_root;
|
||||||
extern bool blkcg_debug_stats;
|
extern bool blkcg_debug_stats;
|
||||||
|
|
||||||
|
void blkg_init_queue(struct request_queue *q);
|
||||||
int blkcg_init_disk(struct gendisk *disk);
|
int blkcg_init_disk(struct gendisk *disk);
|
||||||
void blkcg_exit_disk(struct gendisk *disk);
|
void blkcg_exit_disk(struct gendisk *disk);
|
||||||
|
|
||||||
@ -481,6 +482,7 @@ struct blkcg {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; }
|
static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; }
|
||||||
|
static inline void blkg_init_queue(struct request_queue *q) { }
|
||||||
static inline int blkcg_init_disk(struct gendisk *disk) { return 0; }
|
static inline int blkcg_init_disk(struct gendisk *disk) { return 0; }
|
||||||
static inline void blkcg_exit_disk(struct gendisk *disk) { }
|
static inline void blkcg_exit_disk(struct gendisk *disk) { }
|
||||||
static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; }
|
static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; }
|
||||||
|
@ -430,6 +430,8 @@ struct request_queue *blk_alloc_queue(int node_id)
|
|||||||
init_waitqueue_head(&q->mq_freeze_wq);
|
init_waitqueue_head(&q->mq_freeze_wq);
|
||||||
mutex_init(&q->mq_freeze_lock);
|
mutex_init(&q->mq_freeze_lock);
|
||||||
|
|
||||||
|
blkg_init_queue(q);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init percpu_ref in atomic mode so that it's faster to shutdown.
|
* Init percpu_ref in atomic mode so that it's faster to shutdown.
|
||||||
* See blk_register_queue() for details.
|
* See blk_register_queue() for details.
|
||||||
|
Loading…
Reference in New Issue
Block a user