|
@@ -63,63 +63,6 @@ struct blkio_cgroup *bio_blkio_cgroup(struct bio *bio)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(bio_blkio_cgroup);
|
|
|
|
|
|
-static inline void blkio_update_group_weight(struct blkio_group *blkg,
|
|
|
- int plid, unsigned int weight)
|
|
|
-{
|
|
|
- struct blkio_policy_type *blkiop;
|
|
|
-
|
|
|
- list_for_each_entry(blkiop, &blkio_list, list) {
|
|
|
- /* If this policy does not own the blkg, do not send updates */
|
|
|
- if (blkiop->plid != plid)
|
|
|
- continue;
|
|
|
- if (blkiop->ops.blkio_update_group_weight_fn)
|
|
|
- blkiop->ops.blkio_update_group_weight_fn(blkg->q,
|
|
|
- blkg, weight);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static inline void blkio_update_group_bps(struct blkio_group *blkg, int plid,
|
|
|
- u64 bps, int rw)
|
|
|
-{
|
|
|
- struct blkio_policy_type *blkiop;
|
|
|
-
|
|
|
- list_for_each_entry(blkiop, &blkio_list, list) {
|
|
|
-
|
|
|
- /* If this policy does not own the blkg, do not send updates */
|
|
|
- if (blkiop->plid != plid)
|
|
|
- continue;
|
|
|
-
|
|
|
- if (rw == READ && blkiop->ops.blkio_update_group_read_bps_fn)
|
|
|
- blkiop->ops.blkio_update_group_read_bps_fn(blkg->q,
|
|
|
- blkg, bps);
|
|
|
-
|
|
|
- if (rw == WRITE && blkiop->ops.blkio_update_group_write_bps_fn)
|
|
|
- blkiop->ops.blkio_update_group_write_bps_fn(blkg->q,
|
|
|
- blkg, bps);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static inline void blkio_update_group_iops(struct blkio_group *blkg, int plid,
|
|
|
- u64 iops, int rw)
|
|
|
-{
|
|
|
- struct blkio_policy_type *blkiop;
|
|
|
-
|
|
|
- list_for_each_entry(blkiop, &blkio_list, list) {
|
|
|
-
|
|
|
- /* If this policy does not own the blkg, do not send updates */
|
|
|
- if (blkiop->plid != plid)
|
|
|
- continue;
|
|
|
-
|
|
|
- if (rw == READ && blkiop->ops.blkio_update_group_read_iops_fn)
|
|
|
- blkiop->ops.blkio_update_group_read_iops_fn(blkg->q,
|
|
|
- blkg, iops);
|
|
|
-
|
|
|
- if (rw == WRITE && blkiop->ops.blkio_update_group_write_iops_fn)
|
|
|
- blkiop->ops.blkio_update_group_write_iops_fn(blkg->q,
|
|
|
- blkg,iops);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
#ifdef CONFIG_DEBUG_BLK_CGROUP
|
|
|
/* This should be called with the queue_lock held. */
|
|
|
static void blkio_set_start_group_wait_time(struct blkio_group *blkg,
|
|
@@ -939,33 +882,6 @@ int blkcg_print_cpu_rwstat(struct cgroup *cgrp, struct cftype *cft,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(blkcg_print_cpu_rwstat);
|
|
|
|
|
|
-#ifdef CONFIG_DEBUG_BLK_CGROUP
|
|
|
-static u64 blkg_prfill_avg_queue_size(struct seq_file *sf,
|
|
|
- struct blkg_policy_data *pd, int off)
|
|
|
-{
|
|
|
- u64 samples = blkg_stat_read(&pd->stats.avg_queue_size_samples);
|
|
|
- u64 v = 0;
|
|
|
-
|
|
|
- if (samples) {
|
|
|
- v = blkg_stat_read(&pd->stats.avg_queue_size_sum);
|
|
|
- do_div(v, samples);
|
|
|
- }
|
|
|
- __blkg_prfill_u64(sf, pd, v);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/* print avg_queue_size */
|
|
|
-static int blkcg_print_avg_queue_size(struct cgroup *cgrp, struct cftype *cft,
|
|
|
- struct seq_file *sf)
|
|
|
-{
|
|
|
- struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgrp);
|
|
|
-
|
|
|
- blkcg_print_blkgs(sf, blkcg, blkg_prfill_avg_queue_size,
|
|
|
- BLKIO_POLICY_PROP, 0, false);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-#endif /* CONFIG_DEBUG_BLK_CGROUP */
|
|
|
-
|
|
|
/**
|
|
|
* blkg_conf_prep - parse and prepare for per-blkg config update
|
|
|
* @blkcg: target block cgroup
|
|
@@ -1039,300 +955,11 @@ void blkg_conf_finish(struct blkg_conf_ctx *ctx)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(blkg_conf_finish);
|
|
|
|
|
|
-/* for propio conf */
|
|
|
-static u64 blkg_prfill_weight_device(struct seq_file *sf,
|
|
|
- struct blkg_policy_data *pd, int off)
|
|
|
-{
|
|
|
- if (!pd->conf.weight)
|
|
|
- return 0;
|
|
|
- return __blkg_prfill_u64(sf, pd, pd->conf.weight);
|
|
|
-}
|
|
|
-
|
|
|
-static int blkcg_print_weight_device(struct cgroup *cgrp, struct cftype *cft,
|
|
|
- struct seq_file *sf)
|
|
|
-{
|
|
|
- blkcg_print_blkgs(sf, cgroup_to_blkio_cgroup(cgrp),
|
|
|
- blkg_prfill_weight_device, BLKIO_POLICY_PROP, 0,
|
|
|
- false);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int blkcg_print_weight(struct cgroup *cgrp, struct cftype *cft,
|
|
|
- struct seq_file *sf)
|
|
|
-{
|
|
|
- seq_printf(sf, "%u\n", cgroup_to_blkio_cgroup(cgrp)->weight);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int blkcg_set_weight_device(struct cgroup *cgrp, struct cftype *cft,
|
|
|
- const char *buf)
|
|
|
-{
|
|
|
- struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgrp);
|
|
|
- struct blkg_policy_data *pd;
|
|
|
- struct blkg_conf_ctx ctx;
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = blkg_conf_prep(blkcg, buf, &ctx);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
-
|
|
|
- ret = -EINVAL;
|
|
|
- pd = ctx.blkg->pd[BLKIO_POLICY_PROP];
|
|
|
- if (pd && (!ctx.v || (ctx.v >= BLKIO_WEIGHT_MIN &&
|
|
|
- ctx.v <= BLKIO_WEIGHT_MAX))) {
|
|
|
- pd->conf.weight = ctx.v;
|
|
|
- blkio_update_group_weight(ctx.blkg, BLKIO_POLICY_PROP,
|
|
|
- ctx.v ?: blkcg->weight);
|
|
|
- ret = 0;
|
|
|
- }
|
|
|
-
|
|
|
- blkg_conf_finish(&ctx);
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-static int blkcg_set_weight(struct cgroup *cgrp, struct cftype *cft, u64 val)
|
|
|
-{
|
|
|
- struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgrp);
|
|
|
- struct blkio_group *blkg;
|
|
|
- struct hlist_node *n;
|
|
|
-
|
|
|
- if (val < BLKIO_WEIGHT_MIN || val > BLKIO_WEIGHT_MAX)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- spin_lock(&blkio_list_lock);
|
|
|
- spin_lock_irq(&blkcg->lock);
|
|
|
- blkcg->weight = (unsigned int)val;
|
|
|
-
|
|
|
- hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) {
|
|
|
- struct blkg_policy_data *pd = blkg->pd[BLKIO_POLICY_PROP];
|
|
|
-
|
|
|
- if (pd && !pd->conf.weight)
|
|
|
- blkio_update_group_weight(blkg, BLKIO_POLICY_PROP,
|
|
|
- blkcg->weight);
|
|
|
- }
|
|
|
-
|
|
|
- spin_unlock_irq(&blkcg->lock);
|
|
|
- spin_unlock(&blkio_list_lock);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/* for blk-throttle conf */
|
|
|
-#ifdef CONFIG_BLK_DEV_THROTTLING
|
|
|
-static u64 blkg_prfill_conf_u64(struct seq_file *sf,
|
|
|
- struct blkg_policy_data *pd, int off)
|
|
|
-{
|
|
|
- u64 v = *(u64 *)((void *)&pd->conf + off);
|
|
|
-
|
|
|
- if (!v)
|
|
|
- return 0;
|
|
|
- return __blkg_prfill_u64(sf, pd, v);
|
|
|
-}
|
|
|
-
|
|
|
-static int blkcg_print_conf_u64(struct cgroup *cgrp, struct cftype *cft,
|
|
|
- struct seq_file *sf)
|
|
|
-{
|
|
|
- blkcg_print_blkgs(sf, cgroup_to_blkio_cgroup(cgrp),
|
|
|
- blkg_prfill_conf_u64, BLKIO_POLICY_THROTL,
|
|
|
- cft->private, false);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int blkcg_set_conf_u64(struct cgroup *cgrp, struct cftype *cft,
|
|
|
- const char *buf, int rw,
|
|
|
- void (*update)(struct blkio_group *, int, u64, int))
|
|
|
-{
|
|
|
- struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgrp);
|
|
|
- struct blkg_policy_data *pd;
|
|
|
- struct blkg_conf_ctx ctx;
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = blkg_conf_prep(blkcg, buf, &ctx);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
-
|
|
|
- ret = -EINVAL;
|
|
|
- pd = ctx.blkg->pd[BLKIO_POLICY_THROTL];
|
|
|
- if (pd) {
|
|
|
- *(u64 *)((void *)&pd->conf + cft->private) = ctx.v;
|
|
|
- update(ctx.blkg, BLKIO_POLICY_THROTL, ctx.v ?: -1, rw);
|
|
|
- ret = 0;
|
|
|
- }
|
|
|
-
|
|
|
- blkg_conf_finish(&ctx);
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-static int blkcg_set_conf_bps_r(struct cgroup *cgrp, struct cftype *cft,
|
|
|
- const char *buf)
|
|
|
-{
|
|
|
- return blkcg_set_conf_u64(cgrp, cft, buf, READ, blkio_update_group_bps);
|
|
|
-}
|
|
|
-
|
|
|
-static int blkcg_set_conf_bps_w(struct cgroup *cgrp, struct cftype *cft,
|
|
|
- const char *buf)
|
|
|
-{
|
|
|
- return blkcg_set_conf_u64(cgrp, cft, buf, WRITE, blkio_update_group_bps);
|
|
|
-}
|
|
|
-
|
|
|
-static int blkcg_set_conf_iops_r(struct cgroup *cgrp, struct cftype *cft,
|
|
|
- const char *buf)
|
|
|
-{
|
|
|
- return blkcg_set_conf_u64(cgrp, cft, buf, READ, blkio_update_group_iops);
|
|
|
-}
|
|
|
-
|
|
|
-static int blkcg_set_conf_iops_w(struct cgroup *cgrp, struct cftype *cft,
|
|
|
- const char *buf)
|
|
|
-{
|
|
|
- return blkcg_set_conf_u64(cgrp, cft, buf, WRITE, blkio_update_group_iops);
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
struct cftype blkio_files[] = {
|
|
|
- {
|
|
|
- .name = "weight_device",
|
|
|
- .read_seq_string = blkcg_print_weight_device,
|
|
|
- .write_string = blkcg_set_weight_device,
|
|
|
- .max_write_len = 256,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "weight",
|
|
|
- .read_seq_string = blkcg_print_weight,
|
|
|
- .write_u64 = blkcg_set_weight,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "time",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats, time)),
|
|
|
- .read_seq_string = blkcg_print_stat,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "sectors",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats_cpu, sectors)),
|
|
|
- .read_seq_string = blkcg_print_cpu_stat,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "io_service_bytes",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats_cpu, service_bytes)),
|
|
|
- .read_seq_string = blkcg_print_cpu_rwstat,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "io_serviced",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats_cpu, serviced)),
|
|
|
- .read_seq_string = blkcg_print_cpu_rwstat,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "io_service_time",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats, service_time)),
|
|
|
- .read_seq_string = blkcg_print_rwstat,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "io_wait_time",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats, wait_time)),
|
|
|
- .read_seq_string = blkcg_print_rwstat,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "io_merged",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats, merged)),
|
|
|
- .read_seq_string = blkcg_print_rwstat,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "io_queued",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats, queued)),
|
|
|
- .read_seq_string = blkcg_print_rwstat,
|
|
|
- },
|
|
|
{
|
|
|
.name = "reset_stats",
|
|
|
.write_u64 = blkiocg_reset_stats,
|
|
|
},
|
|
|
-#ifdef CONFIG_BLK_DEV_THROTTLING
|
|
|
- {
|
|
|
- .name = "throttle.read_bps_device",
|
|
|
- .private = offsetof(struct blkio_group_conf, bps[READ]),
|
|
|
- .read_seq_string = blkcg_print_conf_u64,
|
|
|
- .write_string = blkcg_set_conf_bps_r,
|
|
|
- .max_write_len = 256,
|
|
|
- },
|
|
|
-
|
|
|
- {
|
|
|
- .name = "throttle.write_bps_device",
|
|
|
- .private = offsetof(struct blkio_group_conf, bps[WRITE]),
|
|
|
- .read_seq_string = blkcg_print_conf_u64,
|
|
|
- .write_string = blkcg_set_conf_bps_w,
|
|
|
- .max_write_len = 256,
|
|
|
- },
|
|
|
-
|
|
|
- {
|
|
|
- .name = "throttle.read_iops_device",
|
|
|
- .private = offsetof(struct blkio_group_conf, iops[READ]),
|
|
|
- .read_seq_string = blkcg_print_conf_u64,
|
|
|
- .write_string = blkcg_set_conf_iops_r,
|
|
|
- .max_write_len = 256,
|
|
|
- },
|
|
|
-
|
|
|
- {
|
|
|
- .name = "throttle.write_iops_device",
|
|
|
- .private = offsetof(struct blkio_group_conf, iops[WRITE]),
|
|
|
- .read_seq_string = blkcg_print_conf_u64,
|
|
|
- .write_string = blkcg_set_conf_iops_w,
|
|
|
- .max_write_len = 256,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "throttle.io_service_bytes",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_THROTL,
|
|
|
- offsetof(struct blkio_group_stats_cpu, service_bytes)),
|
|
|
- .read_seq_string = blkcg_print_cpu_rwstat,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "throttle.io_serviced",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_THROTL,
|
|
|
- offsetof(struct blkio_group_stats_cpu, serviced)),
|
|
|
- .read_seq_string = blkcg_print_cpu_rwstat,
|
|
|
- },
|
|
|
-#endif /* CONFIG_BLK_DEV_THROTTLING */
|
|
|
-
|
|
|
-#ifdef CONFIG_DEBUG_BLK_CGROUP
|
|
|
- {
|
|
|
- .name = "avg_queue_size",
|
|
|
- .read_seq_string = blkcg_print_avg_queue_size,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "group_wait_time",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats, group_wait_time)),
|
|
|
- .read_seq_string = blkcg_print_stat,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "idle_time",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats, idle_time)),
|
|
|
- .read_seq_string = blkcg_print_stat,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "empty_time",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats, empty_time)),
|
|
|
- .read_seq_string = blkcg_print_stat,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "dequeue",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats, dequeue)),
|
|
|
- .read_seq_string = blkcg_print_stat,
|
|
|
- },
|
|
|
- {
|
|
|
- .name = "unaccounted_time",
|
|
|
- .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
|
|
|
- offsetof(struct blkio_group_stats, unaccounted_time)),
|
|
|
- .read_seq_string = blkcg_print_stat,
|
|
|
- },
|
|
|
-#endif
|
|
|
{ } /* terminate */
|
|
|
};
|
|
|
|