ARM/ARM64: config: enable DM_INIT configuration
[platform/kernel/linux-rpi.git] / block / blk-cgroup.c
index 38b9f76..ce5858d 100644 (file)
@@ -633,6 +633,14 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
 
        q = bdev->bd_disk->queue;
 
+       /*
+        * blkcg_deactivate_policy() requires queue to be frozen, we can grab
+        * q_usage_counter to prevent concurrent with blkcg_deactivate_policy().
+        */
+       ret = blk_queue_enter(q, 0);
+       if (ret)
+               goto fail;
+
        rcu_read_lock();
        spin_lock_irq(&q->queue_lock);
 
@@ -667,13 +675,13 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
                new_blkg = blkg_alloc(pos, q, GFP_KERNEL);
                if (unlikely(!new_blkg)) {
                        ret = -ENOMEM;
-                       goto fail;
+                       goto fail_exit_queue;
                }
 
                if (radix_tree_preload(GFP_KERNEL)) {
                        blkg_free(new_blkg);
                        ret = -ENOMEM;
-                       goto fail;
+                       goto fail_exit_queue;
                }
 
                rcu_read_lock();
@@ -702,6 +710,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
                        goto success;
        }
 success:
+       blk_queue_exit(q);
        ctx->bdev = bdev;
        ctx->blkg = blkg;
        ctx->body = input;
@@ -712,6 +721,8 @@ fail_preloaded:
 fail_unlock:
        spin_unlock_irq(&q->queue_lock);
        rcu_read_unlock();
+fail_exit_queue:
+       blk_queue_exit(q);
 fail:
        blkdev_put_no_open(bdev);
        /*
@@ -844,11 +855,11 @@ static void blkcg_fill_root_iostats(void)
                        blk_queue_root_blkg(bdev->bd_disk->queue);
                struct blkg_iostat tmp;
                int cpu;
+               unsigned long flags;
 
                memset(&tmp, 0, sizeof(tmp));
                for_each_possible_cpu(cpu) {
                        struct disk_stats *cpu_dkstats;
-                       unsigned long flags;
 
                        cpu_dkstats = per_cpu_ptr(bdev->bd_stats, cpu);
                        tmp.ios[BLKG_IOSTAT_READ] +=
@@ -864,11 +875,11 @@ static void blkcg_fill_root_iostats(void)
                                cpu_dkstats->sectors[STAT_WRITE] << 9;
                        tmp.bytes[BLKG_IOSTAT_DISCARD] +=
                                cpu_dkstats->sectors[STAT_DISCARD] << 9;
-
-                       flags = u64_stats_update_begin_irqsave(&blkg->iostat.sync);
-                       blkg_iostat_set(&blkg->iostat.cur, &tmp);
-                       u64_stats_update_end_irqrestore(&blkg->iostat.sync, flags);
                }
+
+               flags = u64_stats_update_begin_irqsave(&blkg->iostat.sync);
+               blkg_iostat_set(&blkg->iostat.cur, &tmp);
+               u64_stats_update_end_irqrestore(&blkg->iostat.sync, flags);
        }
 }
 
@@ -1875,12 +1886,8 @@ EXPORT_SYMBOL_GPL(bio_associate_blkg);
  */
 void bio_clone_blkg_association(struct bio *dst, struct bio *src)
 {
-       if (src->bi_blkg) {
-               if (dst->bi_blkg)
-                       blkg_put(dst->bi_blkg);
-               blkg_get(src->bi_blkg);
-               dst->bi_blkg = src->bi_blkg;
-       }
+       if (src->bi_blkg)
+               bio_associate_blkg_from_css(dst, &bio_blkcg(src)->css);
 }
 EXPORT_SYMBOL_GPL(bio_clone_blkg_association);
 
@@ -1897,10 +1904,11 @@ void blk_cgroup_bio_start(struct bio *bio)
 {
        int rwd = blk_cgroup_io_type(bio), cpu;
        struct blkg_iostat_set *bis;
+       unsigned long flags;
 
        cpu = get_cpu();
        bis = per_cpu_ptr(bio->bi_blkg->iostat_cpu, cpu);
-       u64_stats_update_begin(&bis->sync);
+       flags = u64_stats_update_begin_irqsave(&bis->sync);
 
        /*
         * If the bio is flagged with BIO_CGROUP_ACCT it means this is a split
@@ -1912,7 +1920,7 @@ void blk_cgroup_bio_start(struct bio *bio)
        }
        bis->cur.ios[rwd]++;
 
-       u64_stats_update_end(&bis->sync);
+       u64_stats_update_end_irqrestore(&bis->sync, flags);
        if (cgroup_subsys_on_dfl(io_cgrp_subsys))
                cgroup_rstat_updated(bio->bi_blkg->blkcg->css.cgroup, cpu);
        put_cpu();