Skip to content

Commit

Permalink
blkcg: use CGROUP_WEIGHT_* scale for io.weight on the unified hierarchy
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Tejun Heo authored and Jens Axboe committed Aug 18, 2015
1 parent 3ecca62 commit 69d7fde
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Documentation/cgroups/unified-hierarchy.txt
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ may be specified in any order and not all pairs have to be specified.

The weight setting, currently only available and effective if
cfq-iosched is in use for the target device. The weight is
between 10 and 1000 and defaults to 500. The first line
between 1 and 10000 and defaults to 100. The first line
always contains the default weight in the following format to
use when per-device setting is missing.

Expand Down
21 changes: 21 additions & 0 deletions block/blk-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1143,11 +1143,32 @@ static int blkcg_can_attach(struct cgroup_subsys_state *css,
return ret;
}

static void blkcg_bind(struct cgroup_subsys_state *root_css)
{
int i;

mutex_lock(&blkcg_pol_mutex);

for (i = 0; i < BLKCG_MAX_POLS; i++) {
struct blkcg_policy *pol = blkcg_policy[i];
struct blkcg *blkcg;

if (!pol || !pol->cpd_bind_fn)
continue;

list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node)
if (blkcg->cpd[pol->plid])
pol->cpd_bind_fn(blkcg->cpd[pol->plid]);
}
mutex_unlock(&blkcg_pol_mutex);
}

struct cgroup_subsys io_cgrp_subsys = {
.css_alloc = blkcg_css_alloc,
.css_offline = blkcg_css_offline,
.css_free = blkcg_css_free,
.can_attach = blkcg_can_attach,
.bind = blkcg_bind,
.dfl_cftypes = blkcg_files,
.legacy_cftypes = blkcg_legacy_files,
.legacy_name = "blkio",
Expand Down
55 changes: 40 additions & 15 deletions block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,9 @@ static void cfq_init_cfqg_base(struct cfq_group *cfqg)
}

#ifdef CONFIG_CFQ_GROUP_IOSCHED
static int __cfq_set_weight(struct cgroup_subsys_state *css, u64 val,
bool on_dfl, bool reset_dev, bool is_leaf_weight);

static void cfqg_stats_exit(struct cfqg_stats *stats)
{
blkg_rwstat_exit(&stats->merged);
Expand Down Expand Up @@ -1578,21 +1581,34 @@ static struct blkcg_policy_data *cfq_cpd_alloc(gfp_t gfp)
static void cfq_cpd_init(struct blkcg_policy_data *cpd)
{
struct cfq_group_data *cgd = cpd_to_cfqgd(cpd);
unsigned int weight = cgroup_on_dfl(blkcg_root.css.cgroup) ?
CGROUP_WEIGHT_DFL : CFQ_WEIGHT_LEGACY_DFL;

if (cpd_to_blkcg(cpd) == &blkcg_root) {
cgd->weight = 2 * CFQ_WEIGHT_LEGACY_DFL;
cgd->leaf_weight = 2 * CFQ_WEIGHT_LEGACY_DFL;
} else {
cgd->weight = CFQ_WEIGHT_LEGACY_DFL;
cgd->leaf_weight = CFQ_WEIGHT_LEGACY_DFL;
}
if (cpd_to_blkcg(cpd) == &blkcg_root)
weight *= 2;

cgd->weight = weight;
cgd->leaf_weight = weight;
}

static void cfq_cpd_free(struct blkcg_policy_data *cpd)
{
kfree(cpd_to_cfqgd(cpd));
}

static void cfq_cpd_bind(struct blkcg_policy_data *cpd)
{
struct blkcg *blkcg = cpd_to_blkcg(cpd);
bool on_dfl = cgroup_on_dfl(blkcg_root.css.cgroup);
unsigned int weight = on_dfl ? CGROUP_WEIGHT_DFL : CFQ_WEIGHT_LEGACY_DFL;

if (blkcg == &blkcg_root)
weight *= 2;

WARN_ON_ONCE(__cfq_set_weight(&blkcg->css, weight, on_dfl, true, false));
WARN_ON_ONCE(__cfq_set_weight(&blkcg->css, weight, on_dfl, true, true));
}

static struct blkg_policy_data *cfq_pd_alloc(gfp_t gfp, int node)
{
struct cfq_group *cfqg;
Expand Down Expand Up @@ -1742,6 +1758,8 @@ static ssize_t __cfqg_set_weight_device(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off,
bool on_dfl, bool is_leaf_weight)
{
unsigned int min = on_dfl ? CGROUP_WEIGHT_MIN : CFQ_WEIGHT_LEGACY_MIN;
unsigned int max = on_dfl ? CGROUP_WEIGHT_MAX : CFQ_WEIGHT_LEGACY_MAX;
struct blkcg *blkcg = css_to_blkcg(of_css(of));
struct blkg_conf_ctx ctx;
struct cfq_group *cfqg;
Expand Down Expand Up @@ -1769,7 +1787,7 @@ static ssize_t __cfqg_set_weight_device(struct kernfs_open_file *of,
cfqgd = blkcg_to_cfqgd(blkcg);

ret = -ERANGE;
if (!v || (v >= CFQ_WEIGHT_LEGACY_MIN && v <= CFQ_WEIGHT_LEGACY_MAX)) {
if (!v || (v >= min && v <= max)) {
if (!is_leaf_weight) {
cfqg->dev_weight = v;
cfqg->new_weight = v ?: cfqgd->weight;
Expand Down Expand Up @@ -1797,15 +1815,17 @@ static ssize_t cfqg_set_leaf_weight_device(struct kernfs_open_file *of,
}

static int __cfq_set_weight(struct cgroup_subsys_state *css, u64 val,
bool is_leaf_weight)
bool on_dfl, bool reset_dev, bool is_leaf_weight)
{
unsigned int min = on_dfl ? CGROUP_WEIGHT_MIN : CFQ_WEIGHT_LEGACY_MIN;
unsigned int max = on_dfl ? CGROUP_WEIGHT_MAX : CFQ_WEIGHT_LEGACY_MAX;
struct blkcg *blkcg = css_to_blkcg(css);
struct blkcg_gq *blkg;
struct cfq_group_data *cfqgd;
int ret = 0;

if (val < CFQ_WEIGHT_LEGACY_MIN || val > CFQ_WEIGHT_LEGACY_MAX)
return -EINVAL;
if (val < min || val > max)
return -ERANGE;

spin_lock_irq(&blkcg->lock);
cfqgd = blkcg_to_cfqgd(blkcg);
Expand All @@ -1826,9 +1846,13 @@ static int __cfq_set_weight(struct cgroup_subsys_state *css, u64 val,
continue;

if (!is_leaf_weight) {
if (reset_dev)
cfqg->dev_weight = 0;
if (!cfqg->dev_weight)
cfqg->new_weight = cfqgd->weight;
} else {
if (reset_dev)
cfqg->dev_leaf_weight = 0;
if (!cfqg->dev_leaf_weight)
cfqg->new_leaf_weight = cfqgd->leaf_weight;
}
Expand All @@ -1842,13 +1866,13 @@ static int __cfq_set_weight(struct cgroup_subsys_state *css, u64 val,
static int cfq_set_weight(struct cgroup_subsys_state *css, struct cftype *cft,
u64 val)
{
return __cfq_set_weight(css, val, false);
return __cfq_set_weight(css, val, false, false, false);
}

static int cfq_set_leaf_weight(struct cgroup_subsys_state *css,
struct cftype *cft, u64 val)
{
return __cfq_set_weight(css, val, true);
return __cfq_set_weight(css, val, false, false, true);
}

static int cfqg_print_stat(struct seq_file *sf, void *v)
Expand Down Expand Up @@ -2135,7 +2159,7 @@ static ssize_t cfq_set_weight_on_dfl(struct kernfs_open_file *of,
/* "WEIGHT" or "default WEIGHT" sets the default weight */
v = simple_strtoull(buf, &endp, 0);
if (*endp == '\0' || sscanf(buf, "default %llu", &v) == 1) {
ret = __cfq_set_weight(of_css(of), v, false);
ret = __cfq_set_weight(of_css(of), v, true, false, false);
return ret ?: nbytes;
}

Expand Down Expand Up @@ -4512,9 +4536,9 @@ static int cfq_init_queue(struct request_queue *q, struct elevator_type *e)
goto out_free;

cfq_init_cfqg_base(cfqd->root_group);
#endif
cfqd->root_group->weight = 2 * CFQ_WEIGHT_LEGACY_DFL;
cfqd->root_group->leaf_weight = 2 * CFQ_WEIGHT_LEGACY_DFL;
#endif

/*
* Not strictly needed (since RB_ROOT just clears the node and we
Expand Down Expand Up @@ -4715,6 +4739,7 @@ static struct blkcg_policy blkcg_policy_cfq = {
.cpd_alloc_fn = cfq_cpd_alloc,
.cpd_init_fn = cfq_cpd_init,
.cpd_free_fn = cfq_cpd_free,
.cpd_bind_fn = cfq_cpd_bind,

.pd_alloc_fn = cfq_pd_alloc,
.pd_init_fn = cfq_pd_init,
Expand Down
2 changes: 2 additions & 0 deletions include/linux/blk-cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ struct blkcg_gq {
typedef struct blkcg_policy_data *(blkcg_pol_alloc_cpd_fn)(gfp_t gfp);
typedef void (blkcg_pol_init_cpd_fn)(struct blkcg_policy_data *cpd);
typedef void (blkcg_pol_free_cpd_fn)(struct blkcg_policy_data *cpd);
typedef void (blkcg_pol_bind_cpd_fn)(struct blkcg_policy_data *cpd);
typedef struct blkg_policy_data *(blkcg_pol_alloc_pd_fn)(gfp_t gfp, int node);
typedef void (blkcg_pol_init_pd_fn)(struct blkg_policy_data *pd);
typedef void (blkcg_pol_online_pd_fn)(struct blkg_policy_data *pd);
Expand All @@ -155,6 +156,7 @@ struct blkcg_policy {
blkcg_pol_alloc_cpd_fn *cpd_alloc_fn;
blkcg_pol_init_cpd_fn *cpd_init_fn;
blkcg_pol_free_cpd_fn *cpd_free_fn;
blkcg_pol_bind_cpd_fn *cpd_bind_fn;

blkcg_pol_alloc_pd_fn *pd_alloc_fn;
blkcg_pol_init_pd_fn *pd_init_fn;
Expand Down

0 comments on commit 69d7fde

Please sign in to comment.