aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-01-09 11:05:13 -0500
committerTejun Heo <tj@kernel.org>2013-01-09 11:05:13 -0500
commit810ecfa765f8be20c8d9c468885b3403a2232d2f (patch)
tree0c9173defed8de28cf43d972b8e36b48fbcc6f24 /block
parent548bc8e1b38e48653a90f48f636f8d253504f8a2 (diff)
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.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index f9797b244eb3..87ea95d1f533 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)
504 * 504 *
505 * This function invokes @prfill on each blkg of @blkcg if pd for the 505 * This function invokes @prfill on each blkg of @blkcg if pd for the
506 * policy specified by @pol exists. @prfill is invoked with @sf, the 506 * policy specified by @pol exists. @prfill is invoked with @sf, the
507 * policy data and @data. If @show_total is %true, the sum of the return 507 * policy data and @data and the matching queue lock held. If @show_total
508 * values from @prfill is printed with "Total" label at the end. 508 * is %true, the sum of the return values from @prfill is printed with
509 * "Total" label at the end.
509 * 510 *
510 * This is to be used to construct print functions for 511 * This is to be used to construct print functions for
511 * cftype->read_seq_string method. 512 * cftype->read_seq_string method.
@@ -520,11 +521,14 @@ void blkcg_print_blkgs(struct seq_file *sf, struct blkcg *blkcg,
520 struct hlist_node *n; 521 struct hlist_node *n;
521 u64 total = 0; 522 u64 total = 0;
522 523
523 spin_lock_irq(&blkcg->lock); 524 rcu_read_lock();
524 hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) 525 hlist_for_each_entry_rcu(blkg, n, &blkcg->blkg_list, blkcg_node) {
526 spin_lock_irq(blkg->q->queue_lock);
525 if (blkcg_policy_enabled(blkg->q, pol)) 527 if (blkcg_policy_enabled(blkg->q, pol))
526 total += prfill(sf, blkg->pd[pol->plid], data); 528 total += prfill(sf, blkg->pd[pol->plid], data);
527 spin_unlock_irq(&blkcg->lock); 529 spin_unlock_irq(blkg->q->queue_lock);
530 }
531 rcu_read_unlock();
528 532
529 if (show_total) 533 if (show_total)
530 seq_printf(sf, "Total %llu\n", (unsigned long long)total); 534 seq_printf(sf, "Total %llu\n", (unsigned long long)total);