aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2015-08-18 17:55:36 -0400
committerJens Axboe <axboe@fb.com>2015-08-18 18:49:36 -0400
commit69d7fde5909b614114343974cfc52cb8ff30b544 (patch)
tree231d68d331b286767109c616823781ed030ecb2b
parent3ecca62931ee6a30822a1ab7299bc8b8a21e5288 (diff)
blkcg: use CGROUP_WEIGHT_* scale for io.weight on the unified hierarchy
cgroup is trying to make interface consistent across different controllers. For weight based resource control, the knob should have the range [1, 10000] and default to 100. This patch updates cfq-iosched so that the weight range conforms. The internal calculations have enough range and the widening of the weight range shouldn't cause any problem. * blkcg_policy->cpd_bind_fn() is added. If present, this is invoked when blkcg is attached to a hierarchy. * cfq_cpd_init() is updated to use the new default value on the unified hierarchy. * cfq_cpd_bind() callback is implemented to clear per-blkg configs and apply the default config matching the hierarchy type. * cfqd->root_group->[leaf_]weight initialization in cfq_init_queue() is moved into !CONFIG_CFQ_GROUP_IOSCHED block. cfq_cpd_bind() is now responsible for initializing the initial weights when blkcg is enabled. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Vivek Goyal <vgoyal@redhat.com> Cc: Arianna Avanzini <avanzini.arianna@gmail.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--Documentation/cgroups/unified-hierarchy.txt2
-rw-r--r--block/blk-cgroup.c21
-rw-r--r--block/cfq-iosched.c55
-rw-r--r--include/linux/blk-cgroup.h2
4 files changed, 64 insertions, 16 deletions
diff --git a/Documentation/cgroups/unified-hierarchy.txt b/Documentation/cgroups/unified-hierarchy.txt
index bd1ce15d5178..e0975c2cf03d 100644
--- a/Documentation/cgroups/unified-hierarchy.txt
+++ b/Documentation/cgroups/unified-hierarchy.txt
@@ -464,7 +464,7 @@ may be specified in any order and not all pairs have to be specified.
464 464
465 The weight setting, currently only available and effective if 465 The weight setting, currently only available and effective if
466 cfq-iosched is in use for the target device. The weight is 466 cfq-iosched is in use for the target device. The weight is
467 between 10 and 1000 and defaults to 500. The first line 467 between 1 and 10000 and defaults to 100. The first line
468 always contains the default weight in the following format to 468 always contains the default weight in the following format to
469 use when per-device setting is missing. 469 use when per-device setting is missing.
470 470
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 88bdb73bd5e0..ac8370cb2515 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -1143,11 +1143,32 @@ static int blkcg_can_attach(struct cgroup_subsys_state *css,
1143 return ret; 1143 return ret;
1144} 1144}
1145 1145
1146static void blkcg_bind(struct cgroup_subsys_state *root_css)
1147{
1148 int i;
1149
1150 mutex_lock(&blkcg_pol_mutex);
1151
1152 for (i = 0; i < BLKCG_MAX_POLS; i++) {
1153 struct blkcg_policy *pol = blkcg_policy[i];
1154 struct blkcg *blkcg;
1155
1156 if (!pol || !pol->cpd_bind_fn)
1157 continue;
1158
1159 list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node)
1160 if (blkcg->cpd[pol->plid])
1161 pol->cpd_bind_fn(blkcg->cpd[pol->plid]);
1162 }
1163 mutex_unlock(&blkcg_pol_mutex);
1164}
1165
1146struct cgroup_subsys io_cgrp_subsys = { 1166struct cgroup_subsys io_cgrp_subsys = {
1147 .css_alloc = blkcg_css_alloc, 1167 .css_alloc = blkcg_css_alloc,
1148 .css_offline = blkcg_css_offline, 1168 .css_offline = blkcg_css_offline,
1149 .css_free = blkcg_css_free, 1169 .css_free = blkcg_css_free,
1150 .can_attach = blkcg_can_attach, 1170 .can_attach = blkcg_can_attach,
1171 .bind = blkcg_bind,
1151 .dfl_cftypes = blkcg_files, 1172 .dfl_cftypes = blkcg_files,
1152 .legacy_cftypes = blkcg_legacy_files, 1173 .legacy_cftypes = blkcg_legacy_files,
1153 .legacy_name = "blkio", 1174 .legacy_name = "blkio",
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 0fe721eaff28..04de88463a98 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1522,6 +1522,9 @@ static void cfq_init_cfqg_base(struct cfq_group *cfqg)
1522} 1522}
1523 1523
1524#ifdef CONFIG_CFQ_GROUP_IOSCHED 1524#ifdef CONFIG_CFQ_GROUP_IOSCHED
1525static int __cfq_set_weight(struct cgroup_subsys_state *css, u64 val,
1526 bool on_dfl, bool reset_dev, bool is_leaf_weight);
1527
1525static void cfqg_stats_exit(struct cfqg_stats *stats) 1528static void cfqg_stats_exit(struct cfqg_stats *stats)
1526{ 1529{
1527 blkg_rwstat_exit(&stats->merged); 1530 blkg_rwstat_exit(&stats->merged);
@@ -1578,14 +1581,14 @@ static struct blkcg_policy_data *cfq_cpd_alloc(gfp_t gfp)
1578static void cfq_cpd_init(struct blkcg_policy_data *cpd) 1581static void cfq_cpd_init(struct blkcg_policy_data *cpd)
1579{ 1582{
1580 struct cfq_group_data *cgd = cpd_to_cfqgd(cpd); 1583 struct cfq_group_data *cgd = cpd_to_cfqgd(cpd);
1584 unsigned int weight = cgroup_on_dfl(blkcg_root.css.cgroup) ?
1585 CGROUP_WEIGHT_DFL : CFQ_WEIGHT_LEGACY_DFL;
1581 1586
1582 if (cpd_to_blkcg(cpd) == &blkcg_root) { 1587 if (cpd_to_blkcg(cpd) == &blkcg_root)
1583 cgd->weight = 2 * CFQ_WEIGHT_LEGACY_DFL; 1588 weight *= 2;
1584 cgd->leaf_weight = 2 * CFQ_WEIGHT_LEGACY_DFL; 1589
1585 } else { 1590 cgd->weight = weight;
1586 cgd->weight = CFQ_WEIGHT_LEGACY_DFL; 1591 cgd->leaf_weight = weight;
1587 cgd->leaf_weight = CFQ_WEIGHT_LEGACY_DFL;
1588 }
1589} 1592}
1590 1593
1591static void cfq_cpd_free(struct blkcg_policy_data *cpd) 1594static void cfq_cpd_free(struct blkcg_policy_data *cpd)
@@ -1593,6 +1596,19 @@ static void cfq_cpd_free(struct blkcg_policy_data *cpd)
1593 kfree(cpd_to_cfqgd(cpd)); 1596 kfree(cpd_to_cfqgd(cpd));
1594} 1597}
1595 1598
1599static void cfq_cpd_bind(struct blkcg_policy_data *cpd)
1600{
1601 struct blkcg *blkcg = cpd_to_blkcg(cpd);
1602 bool on_dfl = cgroup_on_dfl(blkcg_root.css.cgroup);
1603 unsigned int weight = on_dfl ? CGROUP_WEIGHT_DFL : CFQ_WEIGHT_LEGACY_DFL;
1604
1605 if (blkcg == &blkcg_root)
1606 weight *= 2;
1607
1608 WARN_ON_ONCE(__cfq_set_weight(&blkcg->css, weight, on_dfl, true, false));
1609 WARN_ON_ONCE(__cfq_set_weight(&blkcg->css, weight, on_dfl, true, true));
1610}
1611
1596static struct blkg_policy_data *cfq_pd_alloc(gfp_t gfp, int node) 1612static struct blkg_policy_data *cfq_pd_alloc(gfp_t gfp, int node)
1597{ 1613{
1598 struct cfq_group *cfqg; 1614 struct cfq_group *cfqg;
@@ -1742,6 +1758,8 @@ static ssize_t __cfqg_set_weight_device(struct kernfs_open_file *of,
1742 char *buf, size_t nbytes, loff_t off, 1758 char *buf, size_t nbytes, loff_t off,
1743 bool on_dfl, bool is_leaf_weight) 1759 bool on_dfl, bool is_leaf_weight)
1744{ 1760{
1761 unsigned int min = on_dfl ? CGROUP_WEIGHT_MIN : CFQ_WEIGHT_LEGACY_MIN;
1762 unsigned int max = on_dfl ? CGROUP_WEIGHT_MAX : CFQ_WEIGHT_LEGACY_MAX;
1745 struct blkcg *blkcg = css_to_blkcg(of_css(of)); 1763 struct blkcg *blkcg = css_to_blkcg(of_css(of));
1746 struct blkg_conf_ctx ctx; 1764 struct blkg_conf_ctx ctx;
1747 struct cfq_group *cfqg; 1765 struct cfq_group *cfqg;
@@ -1769,7 +1787,7 @@ static ssize_t __cfqg_set_weight_device(struct kernfs_open_file *of,
1769 cfqgd = blkcg_to_cfqgd(blkcg); 1787 cfqgd = blkcg_to_cfqgd(blkcg);
1770 1788
1771 ret = -ERANGE; 1789 ret = -ERANGE;
1772 if (!v || (v >= CFQ_WEIGHT_LEGACY_MIN && v <= CFQ_WEIGHT_LEGACY_MAX)) { 1790 if (!v || (v >= min && v <= max)) {
1773 if (!is_leaf_weight) { 1791 if (!is_leaf_weight) {
1774 cfqg->dev_weight = v; 1792 cfqg->dev_weight = v;
1775 cfqg->new_weight = v ?: cfqgd->weight; 1793 cfqg->new_weight = v ?: cfqgd->weight;
@@ -1797,15 +1815,17 @@ static ssize_t cfqg_set_leaf_weight_device(struct kernfs_open_file *of,
1797} 1815}
1798 1816
1799static int __cfq_set_weight(struct cgroup_subsys_state *css, u64 val, 1817static int __cfq_set_weight(struct cgroup_subsys_state *css, u64 val,
1800 bool is_leaf_weight) 1818 bool on_dfl, bool reset_dev, bool is_leaf_weight)
1801{ 1819{
1820 unsigned int min = on_dfl ? CGROUP_WEIGHT_MIN : CFQ_WEIGHT_LEGACY_MIN;
1821 unsigned int max = on_dfl ? CGROUP_WEIGHT_MAX : CFQ_WEIGHT_LEGACY_MAX;
1802 struct blkcg *blkcg = css_to_blkcg(css); 1822 struct blkcg *blkcg = css_to_blkcg(css);
1803 struct blkcg_gq *blkg; 1823 struct blkcg_gq *blkg;
1804 struct cfq_group_data *cfqgd; 1824 struct cfq_group_data *cfqgd;
1805 int ret = 0; 1825 int ret = 0;
1806 1826
1807 if (val < CFQ_WEIGHT_LEGACY_MIN || val > CFQ_WEIGHT_LEGACY_MAX) 1827 if (val < min || val > max)
1808 return -EINVAL; 1828 return -ERANGE;
1809 1829
1810 spin_lock_irq(&blkcg->lock); 1830 spin_lock_irq(&blkcg->lock);
1811 cfqgd = blkcg_to_cfqgd(blkcg); 1831 cfqgd = blkcg_to_cfqgd(blkcg);
@@ -1826,9 +1846,13 @@ static int __cfq_set_weight(struct cgroup_subsys_state *css, u64 val,
1826 continue; 1846 continue;
1827 1847
1828 if (!is_leaf_weight) { 1848 if (!is_leaf_weight) {
1849 if (reset_dev)
1850 cfqg->dev_weight = 0;
1829 if (!cfqg->dev_weight) 1851 if (!cfqg->dev_weight)
1830 cfqg->new_weight = cfqgd->weight; 1852 cfqg->new_weight = cfqgd->weight;
1831 } else { 1853 } else {
1854 if (reset_dev)
1855 cfqg->dev_leaf_weight = 0;
1832 if (!cfqg->dev_leaf_weight) 1856 if (!cfqg->dev_leaf_weight)
1833 cfqg->new_leaf_weight = cfqgd->leaf_weight; 1857 cfqg->new_leaf_weight = cfqgd->leaf_weight;
1834 } 1858 }
@@ -1842,13 +1866,13 @@ out:
1842static int cfq_set_weight(struct cgroup_subsys_state *css, struct cftype *cft, 1866static int cfq_set_weight(struct cgroup_subsys_state *css, struct cftype *cft,
1843 u64 val) 1867 u64 val)
1844{ 1868{
1845 return __cfq_set_weight(css, val, false); 1869 return __cfq_set_weight(css, val, false, false, false);
1846} 1870}
1847 1871
1848static int cfq_set_leaf_weight(struct cgroup_subsys_state *css, 1872static int cfq_set_leaf_weight(struct cgroup_subsys_state *css,
1849 struct cftype *cft, u64 val) 1873 struct cftype *cft, u64 val)
1850{ 1874{
1851 return __cfq_set_weight(css, val, true); 1875 return __cfq_set_weight(css, val, false, false, true);
1852} 1876}
1853 1877
1854static int cfqg_print_stat(struct seq_file *sf, void *v) 1878static int cfqg_print_stat(struct seq_file *sf, void *v)
@@ -2135,7 +2159,7 @@ static ssize_t cfq_set_weight_on_dfl(struct kernfs_open_file *of,
2135 /* "WEIGHT" or "default WEIGHT" sets the default weight */ 2159 /* "WEIGHT" or "default WEIGHT" sets the default weight */
2136 v = simple_strtoull(buf, &endp, 0); 2160 v = simple_strtoull(buf, &endp, 0);
2137 if (*endp == '\0' || sscanf(buf, "default %llu", &v) == 1) { 2161 if (*endp == '\0' || sscanf(buf, "default %llu", &v) == 1) {
2138 ret = __cfq_set_weight(of_css(of), v, false); 2162 ret = __cfq_set_weight(of_css(of), v, true, false, false);
2139 return ret ?: nbytes; 2163 return ret ?: nbytes;
2140 } 2164 }
2141 2165
@@ -4512,9 +4536,9 @@ static int cfq_init_queue(struct request_queue *q, struct elevator_type *e)
4512 goto out_free; 4536 goto out_free;
4513 4537
4514 cfq_init_cfqg_base(cfqd->root_group); 4538 cfq_init_cfqg_base(cfqd->root_group);
4515#endif
4516 cfqd->root_group->weight = 2 * CFQ_WEIGHT_LEGACY_DFL; 4539 cfqd->root_group->weight = 2 * CFQ_WEIGHT_LEGACY_DFL;
4517 cfqd->root_group->leaf_weight = 2 * CFQ_WEIGHT_LEGACY_DFL; 4540 cfqd->root_group->leaf_weight = 2 * CFQ_WEIGHT_LEGACY_DFL;
4541#endif
4518 4542
4519 /* 4543 /*
4520 * Not strictly needed (since RB_ROOT just clears the node and we 4544 * Not strictly needed (since RB_ROOT just clears the node and we
@@ -4715,6 +4739,7 @@ static struct blkcg_policy blkcg_policy_cfq = {
4715 .cpd_alloc_fn = cfq_cpd_alloc, 4739 .cpd_alloc_fn = cfq_cpd_alloc,
4716 .cpd_init_fn = cfq_cpd_init, 4740 .cpd_init_fn = cfq_cpd_init,
4717 .cpd_free_fn = cfq_cpd_free, 4741 .cpd_free_fn = cfq_cpd_free,
4742 .cpd_bind_fn = cfq_cpd_bind,
4718 4743
4719 .pd_alloc_fn = cfq_pd_alloc, 4744 .pd_alloc_fn = cfq_pd_alloc,
4720 .pd_init_fn = cfq_pd_init, 4745 .pd_init_fn = cfq_pd_init,
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index 9a7c4bd45fff..0a5cc7a1109b 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -138,6 +138,7 @@ struct blkcg_gq {
138typedef struct blkcg_policy_data *(blkcg_pol_alloc_cpd_fn)(gfp_t gfp); 138typedef struct blkcg_policy_data *(blkcg_pol_alloc_cpd_fn)(gfp_t gfp);
139typedef void (blkcg_pol_init_cpd_fn)(struct blkcg_policy_data *cpd); 139typedef void (blkcg_pol_init_cpd_fn)(struct blkcg_policy_data *cpd);
140typedef void (blkcg_pol_free_cpd_fn)(struct blkcg_policy_data *cpd); 140typedef void (blkcg_pol_free_cpd_fn)(struct blkcg_policy_data *cpd);
141typedef void (blkcg_pol_bind_cpd_fn)(struct blkcg_policy_data *cpd);
141typedef struct blkg_policy_data *(blkcg_pol_alloc_pd_fn)(gfp_t gfp, int node); 142typedef struct blkg_policy_data *(blkcg_pol_alloc_pd_fn)(gfp_t gfp, int node);
142typedef void (blkcg_pol_init_pd_fn)(struct blkg_policy_data *pd); 143typedef void (blkcg_pol_init_pd_fn)(struct blkg_policy_data *pd);
143typedef void (blkcg_pol_online_pd_fn)(struct blkg_policy_data *pd); 144typedef void (blkcg_pol_online_pd_fn)(struct blkg_policy_data *pd);
@@ -155,6 +156,7 @@ struct blkcg_policy {
155 blkcg_pol_alloc_cpd_fn *cpd_alloc_fn; 156 blkcg_pol_alloc_cpd_fn *cpd_alloc_fn;
156 blkcg_pol_init_cpd_fn *cpd_init_fn; 157 blkcg_pol_init_cpd_fn *cpd_init_fn;
157 blkcg_pol_free_cpd_fn *cpd_free_fn; 158 blkcg_pol_free_cpd_fn *cpd_free_fn;
159 blkcg_pol_bind_cpd_fn *cpd_bind_fn;
158 160
159 blkcg_pol_alloc_pd_fn *pd_alloc_fn; 161 blkcg_pol_alloc_pd_fn *pd_alloc_fn;
160 blkcg_pol_init_pd_fn *pd_init_fn; 162 blkcg_pol_init_pd_fn *pd_init_fn;