blk-cgroup: improve policy registration error handling
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>pull/1188/head
parent
86947bdc28
commit
e1a0202c6b
|
|
@ -1727,26 +1727,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;
|
||||||
|
|
@ -1758,8 +1758,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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue