Skip to content

Commit

Permalink
blk-cgroup: improve policy registration error handling
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
2 people authored and Jens Axboe committed Mar 18, 2025
1 parent 86947bd commit e1a0202
Showing 1 changed file with 12 additions and 10 deletions.
22 changes: 12 additions & 10 deletions block/blk-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1727,27 +1727,27 @@ int blkcg_policy_register(struct blkcg_policy *pol)
struct blkcg *blkcg;
int i, ret;

/*
* 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 */
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");
ret = -ENOSPC;
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))
goto err_unlock;

/* register @pol */
pol->plid = i;
blkcg_policy[pol->plid] = pol;
Expand All @@ -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;
Expand Down

0 comments on commit e1a0202

Please sign in to comment.