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;
|
||||
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
|
||||
* without pd_alloc_fn/pd_free_fn can't be activated.
|
||||
*/
|
||||
if ((!pol->cpd_alloc_fn ^ !pol->cpd_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;
|
||||
}
|
||||
|
||||
/* register @pol */
|
||||
pol->plid = i;
|
||||
|
|
@ -1758,8 +1758,10 @@ int blkcg_policy_register(struct blkcg_policy *pol)
|
|||
struct blkcg_policy_data *cpd;
|
||||
|
||||
cpd = pol->cpd_alloc_fn(GFP_KERNEL);
|
||||
if (!cpd)
|
||||
if (!cpd) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_cpds;
|
||||
}
|
||||
|
||||
blkcg->cpd[pol->plid] = cpd;
|
||||
cpd->blkcg = blkcg;
|
||||
|
|
|
|||
Loading…
Reference in New Issue