]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - block/blk-cgroup.c
block: bfq: swap puts in bfqg_and_blkg_put
[mirror_ubuntu-bionic-kernel.git] / block / blk-cgroup.c
index d3f56baee9366220d13db3cc8668ae1a7a1c1994..2b33be93c52f98b5075a0222c5afdf427672d5b4 100644 (file)
@@ -1149,18 +1149,16 @@ int blkcg_init_queue(struct request_queue *q)
        rcu_read_lock();
        spin_lock_irq(q->queue_lock);
        blkg = blkg_create(&blkcg_root, q, new_blkg);
+       if (IS_ERR(blkg))
+               goto err_unlock;
+       q->root_blkg = blkg;
+       q->root_rl.blkg = blkg;
        spin_unlock_irq(q->queue_lock);
        rcu_read_unlock();
 
        if (preloaded)
                radix_tree_preload_end();
 
-       if (IS_ERR(blkg))
-               return PTR_ERR(blkg);
-
-       q->root_blkg = blkg;
-       q->root_rl.blkg = blkg;
-
        ret = blk_throtl_init(q);
        if (ret) {
                spin_lock_irq(q->queue_lock);
@@ -1168,6 +1166,13 @@ int blkcg_init_queue(struct request_queue *q)
                spin_unlock_irq(q->queue_lock);
        }
        return ret;
+
+err_unlock:
+       spin_unlock_irq(q->queue_lock);
+       rcu_read_unlock();
+       if (preloaded)
+               radix_tree_preload_end();
+       return PTR_ERR(blkg);
 }
 
 /**
@@ -1374,17 +1379,12 @@ void blkcg_deactivate_policy(struct request_queue *q,
        __clear_bit(pol->plid, q->blkcg_pols);
 
        list_for_each_entry(blkg, &q->blkg_list, q_node) {
-               /* grab blkcg lock too while removing @pd from @blkg */
-               spin_lock(&blkg->blkcg->lock);
-
                if (blkg->pd[pol->plid]) {
                        if (pol->pd_offline_fn)
                                pol->pd_offline_fn(blkg->pd[pol->plid]);
                        pol->pd_free_fn(blkg->pd[pol->plid]);
                        blkg->pd[pol->plid] = NULL;
                }
-
-               spin_unlock(&blkg->blkcg->lock);
        }
 
        spin_unlock_irq(q->queue_lock);
@@ -1419,6 +1419,11 @@ int blkcg_policy_register(struct blkcg_policy *pol)
        if (i >= BLKCG_MAX_POLS)
                goto err_unlock;
 
+       /* Make sure cpd/pd_alloc_fn and cpd/pd_free_fn in pairs */
+       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;
@@ -1452,7 +1457,7 @@ int blkcg_policy_register(struct blkcg_policy *pol)
        return 0;
 
 err_free_cpds:
-       if (pol->cpd_alloc_fn) {
+       if (pol->cpd_free_fn) {
                list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node) {
                        if (blkcg->cpd[pol->plid]) {
                                pol->cpd_free_fn(blkcg->cpd[pol->plid]);
@@ -1492,7 +1497,7 @@ void blkcg_policy_unregister(struct blkcg_policy *pol)
        /* remove cpds and unregister */
        mutex_lock(&blkcg_pol_mutex);
 
-       if (pol->cpd_alloc_fn) {
+       if (pol->cpd_free_fn) {
                list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node) {
                        if (blkcg->cpd[pol->plid]) {
                                pol->cpd_free_fn(blkcg->cpd[pol->plid]);