diff options
author | Tejun Heo <tj@kernel.org> | 2012-03-05 13:15:01 -0800 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2012-03-06 21:27:22 +0100 |
commit | 2a7f124414b35645049e9c1b125a6f0b470aa5ae (patch) | |
tree | 298d9bc310dc46baed69baf88f083c6db35f0964 /block/cfq-iosched.c | |
parent | 72e06c255181537d0b3e1f657a9ed81655d745b1 (diff) | |
download | blackbird-op-linux-2a7f124414b35645049e9c1b125a6f0b470aa5ae.tar.gz blackbird-op-linux-2a7f124414b35645049e9c1b125a6f0b470aa5ae.zip |
blkcg: move rcu_read_lock() outside of blkio_group get functions
rcu_read_lock() in throtl_get_tb() and cfq_get_cfqg() holds onto
@blkcg while looking up blkg. For API cleanup, the next patch will
make the caller responsible for determining @blkcg to look blkg from
and let them specify it as a parameter. Move rcu read locking out to
the callers to prepare for the change.
-v2: Originally this patch was described as a fix for RCU read locking
bug around @blkg, which Vivek pointed out to be incorrect. It
was from misunderstanding the role of rcu locking as protecting
@blkg not @blkcg. Patch description updated.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r-- | block/cfq-iosched.c | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 61693d3404d0..6063c4482b86 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -1128,13 +1128,10 @@ static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd) struct cfq_group *cfqg = NULL, *__cfqg = NULL; struct request_queue *q = cfqd->queue; - rcu_read_lock(); blkcg = task_blkio_cgroup(current); cfqg = cfq_find_cfqg(cfqd, blkcg); - if (cfqg) { - rcu_read_unlock(); + if (cfqg) return cfqg; - } /* * Need to allocate a group. Allocation of group also needs allocation @@ -1164,7 +1161,6 @@ static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd) if (__cfqg) { kfree(cfqg); - rcu_read_unlock(); return __cfqg; } @@ -1172,7 +1168,6 @@ static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd) cfqg = &cfqd->root_group; cfq_init_add_cfqg_lists(cfqd, cfqg, blkcg); - rcu_read_unlock(); return cfqg; } @@ -2870,6 +2865,8 @@ cfq_find_alloc_queue(struct cfq_data *cfqd, bool is_sync, struct cfq_group *cfqg; retry: + rcu_read_lock(); + cfqg = cfq_get_cfqg(cfqd); cic = cfq_cic_lookup(cfqd, ioc); /* cic always exists here */ @@ -2885,6 +2882,7 @@ retry: cfqq = new_cfqq; new_cfqq = NULL; } else if (gfp_mask & __GFP_WAIT) { + rcu_read_unlock(); spin_unlock_irq(cfqd->queue->queue_lock); new_cfqq = kmem_cache_alloc_node(cfq_pool, gfp_mask | __GFP_ZERO, @@ -2910,6 +2908,7 @@ retry: if (new_cfqq) kmem_cache_free(cfq_pool, new_cfqq); + rcu_read_unlock(); return cfqq; } |