]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
block: fix stacked driver stats init and free
authorJens Axboe <axboe@fb.com>
Tue, 21 Mar 2017 23:20:01 +0000 (17:20 -0600)
committerJens Axboe <axboe@fb.com>
Tue, 21 Mar 2017 23:20:01 +0000 (17:20 -0600)
If a driver allocates a queue for stacked usage, then it does
not currently get stats allocated. This causes the later init
of, eg, writeback throttling to blow up. Move the init to the
queue allocation instead.

Additionally, allow a NULL callback unregistration. This avoids
having the caller check for that, fixing another oops on
removal of a block device that doesn't have poll stats allocated.

Fixes: 34dbad5d26e2 ("blk-stat: convert to callback-based statistics reporting")
Signed-off-by: Jens Axboe <axboe@fb.com>
block/blk-core.c
block/blk-stat.c

index 78d04ddededc2cc1e70d1a7128d68acee67702fc..ad388d5e309a5fb9270b34c91a88091c98ebb3c7 100644 (file)
@@ -720,6 +720,10 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
        if (!q->backing_dev_info)
                goto fail_split;
 
+       q->stats = blk_alloc_queue_stats();
+       if (!q->stats)
+               goto fail_stats;
+
        q->backing_dev_info->ra_pages =
                        (VM_MAX_READAHEAD * 1024) / PAGE_SIZE;
        q->backing_dev_info->capabilities = BDI_CAP_CGROUP_WRITEBACK;
@@ -776,6 +780,8 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
 fail_ref:
        percpu_ref_exit(&q->q_usage_counter);
 fail_bdi:
+       blk_free_queue_stats(q->stats);
+fail_stats:
        bdi_put(q->backing_dev_info);
 fail_split:
        bioset_free(q->bio_split);
@@ -852,10 +858,6 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio);
 
 int blk_init_allocated_queue(struct request_queue *q)
 {
-       q->stats = blk_alloc_queue_stats();
-       if (!q->stats)
-               return -ENOMEM;
-
        q->fq = blk_alloc_flush_queue(q, NUMA_NO_NODE, q->cmd_size);
        if (!q->fq)
                return -ENOMEM;
index 0d8721a60db98c79a75ff462e952ed07e907aa92..188b535cf4d614f6ccb9c579a113132e7e1b5983 100644 (file)
@@ -210,7 +210,8 @@ static void blk_stat_free_callback_rcu(struct rcu_head *head)
 
 void blk_stat_free_callback(struct blk_stat_callback *cb)
 {
-       call_rcu(&cb->rcu, blk_stat_free_callback_rcu);
+       if (cb)
+               call_rcu(&cb->rcu, blk_stat_free_callback_rcu);
 }
 EXPORT_SYMBOL_GPL(blk_stat_free_callback);