diff options
author | Tejun Heo <tj@kernel.org> | 2013-01-09 08:05:13 -0800 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-01-09 08:05:13 -0800 |
commit | 810ecfa765f8be20c8d9c468885b3403a2232d2f (patch) | |
tree | 0c9173defed8de28cf43d972b8e36b48fbcc6f24 /block | |
parent | 548bc8e1b38e48653a90f48f636f8d253504f8a2 (diff) | |
download | linux-3.10-810ecfa765f8be20c8d9c468885b3403a2232d2f.tar.gz linux-3.10-810ecfa765f8be20c8d9c468885b3403a2232d2f.tar.bz2 linux-3.10-810ecfa765f8be20c8d9c468885b3403a2232d2f.zip |
blkcg: make blkcg_print_blkgs() grab q locks instead of blkcg lock
Instead of holding blkcg->lock while walking ->blkg_list and executing
prfill(), RCU walk ->blkg_list and hold the blkg's queue lock while
executing prfill(). This makes prfill() implementations easier as
stats are mostly protected by queue lock.
This will be used to implement hierarchical stats.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-cgroup.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index f9797b244eb..87ea95d1f53 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -504,8 +504,9 @@ static const char *blkg_dev_name(struct blkcg_gq *blkg) * * This function invokes @prfill on each blkg of @blkcg if pd for the * policy specified by @pol exists. @prfill is invoked with @sf, the - * policy data and @data. If @show_total is %true, the sum of the return - * values from @prfill is printed with "Total" label at the end. + * policy data and @data and the matching queue lock held. If @show_total + * is %true, the sum of the return values from @prfill is printed with + * "Total" label at the end. * * This is to be used to construct print functions for * cftype->read_seq_string method. @@ -520,11 +521,14 @@ void blkcg_print_blkgs(struct seq_file *sf, struct blkcg *blkcg, struct hlist_node *n; u64 total = 0; - spin_lock_irq(&blkcg->lock); - hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) + rcu_read_lock(); + hlist_for_each_entry_rcu(blkg, n, &blkcg->blkg_list, blkcg_node) { + spin_lock_irq(blkg->q->queue_lock); if (blkcg_policy_enabled(blkg->q, pol)) total += prfill(sf, blkg->pd[pol->plid], data); - spin_unlock_irq(&blkcg->lock); + spin_unlock_irq(blkg->q->queue_lock); + } + rcu_read_unlock(); if (show_total) seq_printf(sf, "Total %llu\n", (unsigned long long)total); |