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
commit43114018cb0b253fd03c4ff4d42bcdc43389ac1c (patch)
treeabe35791e5ab46d944f35112e25570ab861a7e2f /block
parent0b39920b5f9f3ad37dd259bfa2e9cbca33475b28 (diff)
cfq-iosched: add hierarchical cfq_group statistics
Unfortunately, at this point, there's no way to make the existing statistics hierarchical without creating nasty surprises for the existing users. Just create recursive counterpart of the existing stats. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Vivek Goyal <vgoyal@redhat.com>
Diffstat (limited to 'block')
-rw-r--r--block/cfq-iosched.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 4d75b7944574..b66365b6ba77 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1528,6 +1528,32 @@ static void cfq_pd_offline(struct blkcg_gq *blkg)
1528 cfqg_stats_xfer_dead(blkg_to_cfqg(blkg)); 1528 cfqg_stats_xfer_dead(blkg_to_cfqg(blkg));
1529} 1529}
1530 1530
1531/* offset delta from cfqg->stats to cfqg->dead_stats */
1532static const int dead_stats_off_delta = offsetof(struct cfq_group, dead_stats) -
1533 offsetof(struct cfq_group, stats);
1534
1535/* to be used by recursive prfill, sums live and dead stats recursively */
1536static u64 cfqg_stat_pd_recursive_sum(struct blkg_policy_data *pd, int off)
1537{
1538 u64 sum = 0;
1539
1540 sum += blkg_stat_recursive_sum(pd, off);
1541 sum += blkg_stat_recursive_sum(pd, off + dead_stats_off_delta);
1542 return sum;
1543}
1544
1545/* to be used by recursive prfill, sums live and dead rwstats recursively */
1546static struct blkg_rwstat cfqg_rwstat_pd_recursive_sum(struct blkg_policy_data *pd,
1547 int off)
1548{
1549 struct blkg_rwstat a, b;
1550
1551 a = blkg_rwstat_recursive_sum(pd, off);
1552 b = blkg_rwstat_recursive_sum(pd, off + dead_stats_off_delta);
1553 blkg_rwstat_merge(&a, &b);
1554 return a;
1555}
1556
1531static void cfq_pd_reset_stats(struct blkcg_gq *blkg) 1557static void cfq_pd_reset_stats(struct blkcg_gq *blkg)
1532{ 1558{
1533 struct cfq_group *cfqg = blkg_to_cfqg(blkg); 1559 struct cfq_group *cfqg = blkg_to_cfqg(blkg);
@@ -1732,6 +1758,42 @@ static int cfqg_print_rwstat(struct cgroup *cgrp, struct cftype *cft,
1732 return 0; 1758 return 0;
1733} 1759}
1734 1760
1761static u64 cfqg_prfill_stat_recursive(struct seq_file *sf,
1762 struct blkg_policy_data *pd, int off)
1763{
1764 u64 sum = cfqg_stat_pd_recursive_sum(pd, off);
1765
1766 return __blkg_prfill_u64(sf, pd, sum);
1767}
1768
1769static u64 cfqg_prfill_rwstat_recursive(struct seq_file *sf,
1770 struct blkg_policy_data *pd, int off)
1771{
1772 struct blkg_rwstat sum = cfqg_rwstat_pd_recursive_sum(pd, off);
1773
1774 return __blkg_prfill_rwstat(sf, pd, &sum);
1775}
1776
1777static int cfqg_print_stat_recursive(struct cgroup *cgrp, struct cftype *cft,
1778 struct seq_file *sf)
1779{
1780 struct blkcg *blkcg = cgroup_to_blkcg(cgrp);
1781
1782 blkcg_print_blkgs(sf, blkcg, cfqg_prfill_stat_recursive,
1783 &blkcg_policy_cfq, cft->private, false);
1784 return 0;
1785}
1786
1787static int cfqg_print_rwstat_recursive(struct cgroup *cgrp, struct cftype *cft,
1788 struct seq_file *sf)
1789{
1790 struct blkcg *blkcg = cgroup_to_blkcg(cgrp);
1791
1792 blkcg_print_blkgs(sf, blkcg, cfqg_prfill_rwstat_recursive,
1793 &blkcg_policy_cfq, cft->private, true);
1794 return 0;
1795}
1796
1735#ifdef CONFIG_DEBUG_BLK_CGROUP 1797#ifdef CONFIG_DEBUG_BLK_CGROUP
1736static u64 cfqg_prfill_avg_queue_size(struct seq_file *sf, 1798static u64 cfqg_prfill_avg_queue_size(struct seq_file *sf,
1737 struct blkg_policy_data *pd, int off) 1799 struct blkg_policy_data *pd, int off)
@@ -1803,6 +1865,7 @@ static struct cftype cfq_blkcg_files[] = {
1803 .write_u64 = cfq_set_leaf_weight, 1865 .write_u64 = cfq_set_leaf_weight,
1804 }, 1866 },
1805 1867
1868 /* statistics, covers only the tasks in the cfqg */
1806 { 1869 {
1807 .name = "time", 1870 .name = "time",
1808 .private = offsetof(struct cfq_group, stats.time), 1871 .private = offsetof(struct cfq_group, stats.time),
@@ -1843,6 +1906,48 @@ static struct cftype cfq_blkcg_files[] = {
1843 .private = offsetof(struct cfq_group, stats.queued), 1906 .private = offsetof(struct cfq_group, stats.queued),
1844 .read_seq_string = cfqg_print_rwstat, 1907 .read_seq_string = cfqg_print_rwstat,
1845 }, 1908 },
1909
1910 /* the same statictics which cover the cfqg and its descendants */
1911 {
1912 .name = "time_recursive",
1913 .private = offsetof(struct cfq_group, stats.time),
1914 .read_seq_string = cfqg_print_stat_recursive,
1915 },
1916 {
1917 .name = "sectors_recursive",
1918 .private = offsetof(struct cfq_group, stats.sectors),
1919 .read_seq_string = cfqg_print_stat_recursive,
1920 },
1921 {
1922 .name = "io_service_bytes_recursive",
1923 .private = offsetof(struct cfq_group, stats.service_bytes),
1924 .read_seq_string = cfqg_print_rwstat_recursive,
1925 },
1926 {
1927 .name = "io_serviced_recursive",
1928 .private = offsetof(struct cfq_group, stats.serviced),
1929 .read_seq_string = cfqg_print_rwstat_recursive,
1930 },
1931 {
1932 .name = "io_service_time_recursive",
1933 .private = offsetof(struct cfq_group, stats.service_time),
1934 .read_seq_string = cfqg_print_rwstat_recursive,
1935 },
1936 {
1937 .name = "io_wait_time_recursive",
1938 .private = offsetof(struct cfq_group, stats.wait_time),
1939 .read_seq_string = cfqg_print_rwstat_recursive,
1940 },
1941 {
1942 .name = "io_merged_recursive",
1943 .private = offsetof(struct cfq_group, stats.merged),
1944 .read_seq_string = cfqg_print_rwstat_recursive,
1945 },
1946 {
1947 .name = "io_queued_recursive",
1948 .private = offsetof(struct cfq_group, stats.queued),
1949 .read_seq_string = cfqg_print_rwstat_recursive,
1950 },
1846#ifdef CONFIG_DEBUG_BLK_CGROUP 1951#ifdef CONFIG_DEBUG_BLK_CGROUP
1847 { 1952 {
1848 .name = "avg_queue_size", 1953 .name = "avg_queue_size",