Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 359499
b: refs/heads/master
c: e71357e
h: refs/heads/master
i:
  359497: 7858ef6
  359495: d0312b5
v: v3
  • Loading branch information
Tejun Heo committed Jan 9, 2013
1 parent 355687d commit fd1b1c2
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3c547865902e9fc30dc15941f326fd8039c6628d
refs/heads/master: e71357e118bdd4057e3bc020b9d80fecdd08f588
4 changes: 3 additions & 1 deletion trunk/block/blk-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@

static DEFINE_MUTEX(blkcg_pol_mutex);

struct blkcg blkcg_root = { .cfq_weight = 2 * CFQ_WEIGHT_DEFAULT };
struct blkcg blkcg_root = { .cfq_weight = 2 * CFQ_WEIGHT_DEFAULT,
.cfq_leaf_weight = 2 * CFQ_WEIGHT_DEFAULT, };
EXPORT_SYMBOL_GPL(blkcg_root);

static struct blkcg_policy *blkcg_policy[BLKCG_MAX_POLS];
Expand Down Expand Up @@ -710,6 +711,7 @@ static struct cgroup_subsys_state *blkcg_css_alloc(struct cgroup *cgroup)
return ERR_PTR(-ENOMEM);

blkcg->cfq_weight = CFQ_WEIGHT_DEFAULT;
blkcg->cfq_leaf_weight = CFQ_WEIGHT_DEFAULT;
blkcg->id = atomic64_inc_return(&id_seq); /* root is 0, start from 1 */
done:
spin_lock_init(&blkcg->lock);
Expand Down
1 change: 1 addition & 0 deletions trunk/block/blk-cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct blkcg {

/* TODO: per-policy storage in blkcg */
unsigned int cfq_weight; /* belongs to cfq */
unsigned int cfq_leaf_weight;
};

struct blkg_stat {
Expand Down
134 changes: 126 additions & 8 deletions trunk/block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,21 @@ struct cfq_group {

/* group service_tree key */
u64 vdisktime;

/*
* There are two weights - (internal) weight is the weight of this
* cfqg against the sibling cfqgs. leaf_weight is the wight of
* this cfqg against the child cfqgs. For the root cfqg, both
* weights are kept in sync for backward compatibility.
*/
unsigned int weight;
unsigned int new_weight;
unsigned int dev_weight;

unsigned int leaf_weight;
unsigned int new_leaf_weight;
unsigned int dev_leaf_weight;

/* number of cfqq currently on this group */
int nr_cfqq;

Expand Down Expand Up @@ -1182,10 +1193,16 @@ static void
cfq_update_group_weight(struct cfq_group *cfqg)
{
BUG_ON(!RB_EMPTY_NODE(&cfqg->rb_node));

if (cfqg->new_weight) {
cfqg->weight = cfqg->new_weight;
cfqg->new_weight = 0;
}

if (cfqg->new_leaf_weight) {
cfqg->leaf_weight = cfqg->new_leaf_weight;
cfqg->new_leaf_weight = 0;
}
}

static void
Expand Down Expand Up @@ -1348,6 +1365,7 @@ static void cfq_pd_init(struct blkcg_gq *blkg)

cfq_init_cfqg_base(cfqg);
cfqg->weight = blkg->blkcg->cfq_weight;
cfqg->leaf_weight = blkg->blkcg->cfq_leaf_weight;
}

/*
Expand Down Expand Up @@ -1404,15 +1422,43 @@ static int cfqg_print_weight_device(struct cgroup *cgrp, struct cftype *cft,
return 0;
}

static u64 cfqg_prfill_leaf_weight_device(struct seq_file *sf,
struct blkg_policy_data *pd, int off)
{
struct cfq_group *cfqg = pd_to_cfqg(pd);

if (!cfqg->dev_leaf_weight)
return 0;
return __blkg_prfill_u64(sf, pd, cfqg->dev_leaf_weight);
}

static int cfqg_print_leaf_weight_device(struct cgroup *cgrp,
struct cftype *cft,
struct seq_file *sf)
{
blkcg_print_blkgs(sf, cgroup_to_blkcg(cgrp),
cfqg_prfill_leaf_weight_device, &blkcg_policy_cfq, 0,
false);
return 0;
}

static int cfq_print_weight(struct cgroup *cgrp, struct cftype *cft,
struct seq_file *sf)
{
seq_printf(sf, "%u\n", cgroup_to_blkcg(cgrp)->cfq_weight);
return 0;
}

static int cfqg_set_weight_device(struct cgroup *cgrp, struct cftype *cft,
const char *buf)
static int cfq_print_leaf_weight(struct cgroup *cgrp, struct cftype *cft,
struct seq_file *sf)
{
seq_printf(sf, "%u\n",
cgroup_to_blkcg(cgrp)->cfq_leaf_weight);
return 0;
}

static int __cfqg_set_weight_device(struct cgroup *cgrp, struct cftype *cft,
const char *buf, bool is_leaf_weight)
{
struct blkcg *blkcg = cgroup_to_blkcg(cgrp);
struct blkg_conf_ctx ctx;
Expand All @@ -1426,16 +1472,34 @@ static int cfqg_set_weight_device(struct cgroup *cgrp, struct cftype *cft,
ret = -EINVAL;
cfqg = blkg_to_cfqg(ctx.blkg);
if (!ctx.v || (ctx.v >= CFQ_WEIGHT_MIN && ctx.v <= CFQ_WEIGHT_MAX)) {
cfqg->dev_weight = ctx.v;
cfqg->new_weight = cfqg->dev_weight ?: blkcg->cfq_weight;
if (!is_leaf_weight) {
cfqg->dev_weight = ctx.v;
cfqg->new_weight = ctx.v ?: blkcg->cfq_weight;
} else {
cfqg->dev_leaf_weight = ctx.v;
cfqg->new_leaf_weight = ctx.v ?: blkcg->cfq_leaf_weight;
}
ret = 0;
}

blkg_conf_finish(&ctx);
return ret;
}

static int cfq_set_weight(struct cgroup *cgrp, struct cftype *cft, u64 val)
static int cfqg_set_weight_device(struct cgroup *cgrp, struct cftype *cft,
const char *buf)
{
return __cfqg_set_weight_device(cgrp, cft, buf, false);
}

static int cfqg_set_leaf_weight_device(struct cgroup *cgrp, struct cftype *cft,
const char *buf)
{
return __cfqg_set_weight_device(cgrp, cft, buf, true);
}

static int __cfq_set_weight(struct cgroup *cgrp, struct cftype *cft, u64 val,
bool is_leaf_weight)
{
struct blkcg *blkcg = cgroup_to_blkcg(cgrp);
struct blkcg_gq *blkg;
Expand All @@ -1445,19 +1509,41 @@ static int cfq_set_weight(struct cgroup *cgrp, struct cftype *cft, u64 val)
return -EINVAL;

spin_lock_irq(&blkcg->lock);
blkcg->cfq_weight = (unsigned int)val;

if (!is_leaf_weight)
blkcg->cfq_weight = val;
else
blkcg->cfq_leaf_weight = val;

hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) {
struct cfq_group *cfqg = blkg_to_cfqg(blkg);

if (cfqg && !cfqg->dev_weight)
cfqg->new_weight = blkcg->cfq_weight;
if (!cfqg)
continue;

if (!is_leaf_weight) {
if (!cfqg->dev_weight)
cfqg->new_weight = blkcg->cfq_weight;
} else {
if (!cfqg->dev_leaf_weight)
cfqg->new_leaf_weight = blkcg->cfq_leaf_weight;
}
}

spin_unlock_irq(&blkcg->lock);
return 0;
}

static int cfq_set_weight(struct cgroup *cgrp, struct cftype *cft, u64 val)
{
return __cfq_set_weight(cgrp, cft, val, false);
}

static int cfq_set_leaf_weight(struct cgroup *cgrp, struct cftype *cft, u64 val)
{
return __cfq_set_weight(cgrp, cft, val, true);
}

static int cfqg_print_stat(struct cgroup *cgrp, struct cftype *cft,
struct seq_file *sf)
{
Expand Down Expand Up @@ -1518,6 +1604,37 @@ static struct cftype cfq_blkcg_files[] = {
.read_seq_string = cfq_print_weight,
.write_u64 = cfq_set_weight,
},

/* on root, leaf_weight is mapped to weight */
{
.name = "leaf_weight_device",
.flags = CFTYPE_ONLY_ON_ROOT,
.read_seq_string = cfqg_print_weight_device,
.write_string = cfqg_set_weight_device,
.max_write_len = 256,
},
{
.name = "leaf_weight",
.flags = CFTYPE_ONLY_ON_ROOT,
.read_seq_string = cfq_print_weight,
.write_u64 = cfq_set_weight,
},

/* no such mapping necessary for !roots */
{
.name = "leaf_weight_device",
.flags = CFTYPE_NOT_ON_ROOT,
.read_seq_string = cfqg_print_leaf_weight_device,
.write_string = cfqg_set_leaf_weight_device,
.max_write_len = 256,
},
{
.name = "leaf_weight",
.flags = CFTYPE_NOT_ON_ROOT,
.read_seq_string = cfq_print_leaf_weight,
.write_u64 = cfq_set_leaf_weight,
},

{
.name = "time",
.private = offsetof(struct cfq_group, stats.time),
Expand Down Expand Up @@ -3992,6 +4109,7 @@ static int cfq_init_queue(struct request_queue *q)
cfq_init_cfqg_base(cfqd->root_group);
#endif
cfqd->root_group->weight = 2 * CFQ_WEIGHT_DEFAULT;
cfqd->root_group->leaf_weight = 2 * CFQ_WEIGHT_DEFAULT;

/*
* Not strictly needed (since RB_ROOT just clears the node and we
Expand Down

0 comments on commit fd1b1c2

Please sign in to comment.