blk-cgroup: improve policy registration error handling
[ Upstream commit e1a0202c6bfda24002a3ae2115154fa90104c649 ] This patch improve the returned error code of blkcg_policy_register(). 1. Move the validation check for cpd/pd_alloc_fn and cpd/pd_free_fn function pairs to the start of blkcg_policy_register(). This ensures we immediately return -EINVAL if the function pairs are not correctly provided, rather than returning -ENOSPC after locking and unlocking mutexes unnecessarily. Those locks should not contention any problems, as error of policy registration is a super cold path. 2. Return -ENOMEM when cpd_alloc_fn() failed. Co-authored-by: Wen Tao <wentao@uniontech.com> Signed-off-by: Wen Tao <wentao@uniontech.com> Signed-off-by: Chen Linxuan <chenlinxuan@uniontech.com> Reviewed-by: Michal Koutný <mkoutny@suse.com> Acked-by: Tejun Heo <tj@kernel.org> Reviewed-by: Yu Kuai <yukuai3@huawei.com> Link: https://lore.kernel.org/r/3E333A73B6B6DFC0+20250317022924.150907-1-chenlinxuan@uniontech.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
c60f8684a8
commit
a5a507fa5f
+16
-14
@@ -1725,26 +1725,26 @@ int blkcg_policy_register(struct blkcg_policy *pol)
|
|||||||
struct blkcg *blkcg;
|
struct blkcg *blkcg;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
mutex_lock(&blkcg_pol_register_mutex);
|
|
||||||
mutex_lock(&blkcg_pol_mutex);
|
|
||||||
|
|
||||||
/* find an empty slot */
|
|
||||||
ret = -ENOSPC;
|
|
||||||
for (i = 0; i < BLKCG_MAX_POLS; i++)
|
|
||||||
if (!blkcg_policy[i])
|
|
||||||
break;
|
|
||||||
if (i >= BLKCG_MAX_POLS) {
|
|
||||||
pr_warn("blkcg_policy_register: BLKCG_MAX_POLS too small\n");
|
|
||||||
goto err_unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure cpd/pd_alloc_fn and cpd/pd_free_fn in pairs, and policy
|
* Make sure cpd/pd_alloc_fn and cpd/pd_free_fn in pairs, and policy
|
||||||
* without pd_alloc_fn/pd_free_fn can't be activated.
|
* without pd_alloc_fn/pd_free_fn can't be activated.
|
||||||
*/
|
*/
|
||||||
if ((!pol->cpd_alloc_fn ^ !pol->cpd_free_fn) ||
|
if ((!pol->cpd_alloc_fn ^ !pol->cpd_free_fn) ||
|
||||||
(!pol->pd_alloc_fn ^ !pol->pd_free_fn))
|
(!pol->pd_alloc_fn ^ !pol->pd_free_fn))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mutex_lock(&blkcg_pol_register_mutex);
|
||||||
|
mutex_lock(&blkcg_pol_mutex);
|
||||||
|
|
||||||
|
/* find an empty slot */
|
||||||
|
for (i = 0; i < BLKCG_MAX_POLS; i++)
|
||||||
|
if (!blkcg_policy[i])
|
||||||
|
break;
|
||||||
|
if (i >= BLKCG_MAX_POLS) {
|
||||||
|
pr_warn("blkcg_policy_register: BLKCG_MAX_POLS too small\n");
|
||||||
|
ret = -ENOSPC;
|
||||||
goto err_unlock;
|
goto err_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
/* register @pol */
|
/* register @pol */
|
||||||
pol->plid = i;
|
pol->plid = i;
|
||||||
@@ -1756,8 +1756,10 @@ int blkcg_policy_register(struct blkcg_policy *pol)
|
|||||||
struct blkcg_policy_data *cpd;
|
struct blkcg_policy_data *cpd;
|
||||||
|
|
||||||
cpd = pol->cpd_alloc_fn(GFP_KERNEL);
|
cpd = pol->cpd_alloc_fn(GFP_KERNEL);
|
||||||
if (!cpd)
|
if (!cpd) {
|
||||||
|
ret = -ENOMEM;
|
||||||
goto err_free_cpds;
|
goto err_free_cpds;
|
||||||
|
}
|
||||||
|
|
||||||
blkcg->cpd[pol->plid] = cpd;
|
blkcg->cpd[pol->plid] = cpd;
|
||||||
cpd->blkcg = blkcg;
|
cpd->blkcg = blkcg;
|
||||||
|
|||||||
Reference in New Issue
Block a user