123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- /*
- * Common Block IO controller cgroup interface
- *
- * Based on ideas and code from CFQ, CFS and BFQ:
- * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
- *
- * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
- * Paolo Valente <paolo.valente@unimore.it>
- *
- * Copyright (C) 2009 Vivek Goyal <vgoyal@redhat.com>
- * Nauman Rafique <nauman@google.com>
- */
- #include <linux/ioprio.h>
- #include <linux/kdev_t.h>
- #include <linux/module.h>
- #include <linux/err.h>
- #include <linux/blkdev.h>
- #include <linux/slab.h>
- #include <linux/genhd.h>
- #include <linux/delay.h>
- #include <linux/atomic.h>
- #include "blk-cgroup.h"
- #include "blk.h"
- #define MAX_KEY_LEN 100
- static DEFINE_MUTEX(blkcg_pol_mutex);
- struct blkcg blkcg_root = { .cfq_weight = 2 * CFQ_WEIGHT_DEFAULT };
- EXPORT_SYMBOL_GPL(blkcg_root);
- static struct blkcg_policy *blkcg_policy[BLKCG_MAX_POLS];
- static bool blkcg_policy_enabled(struct request_queue *q,
- const struct blkcg_policy *pol)
- {
- return pol && test_bit(pol->plid, q->blkcg_pols);
- }
- /**
- * blkg_free - free a blkg
- * @blkg: blkg to free
- *
- * Free @blkg which may be partially allocated.
- */
- static void blkg_free(struct blkcg_gq *blkg)
- {
- int i;
- if (!blkg)
- return;
- for (i = 0; i < BLKCG_MAX_POLS; i++) {
- struct blkcg_policy *pol = blkcg_policy[i];
- struct blkg_policy_data *pd = blkg->pd[i];
- if (!pd)
- continue;
- if (pol && pol->pd_exit_fn)
- pol->pd_exit_fn(blkg);
- kfree(pd);
- }
- blk_exit_rl(&blkg->rl);
- kfree(blkg);
- }
- /**
- * blkg_alloc - allocate a blkg
- * @blkcg: block cgroup the new blkg is associated with
- * @q: request_queue the new blkg is associated with
- * @gfp_mask: allocation mask to use
- *
- * Allocate a new blkg assocating @blkcg and @q.
- */
- static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q,
- gfp_t gfp_mask)
- {
- struct blkcg_gq *blkg;
- int i;
- /* alloc and init base part */
- blkg = kzalloc_node(sizeof(*blkg), gfp_mask, q->node);
- if (!blkg)
- return NULL;
- blkg->q = q;
- INIT_LIST_HEAD(&blkg->q_node);
- blkg->blkcg = blkcg;
- blkg->refcnt = 1;
- /* root blkg uses @q->root_rl, init rl only for !root blkgs */
- if (blkcg != &blkcg_root) {
- if (blk_init_rl(&blkg->rl, q, gfp_mask))
- goto err_free;
- blkg->rl.blkg = blkg;
- }
- for (i = 0; i < BLKCG_MAX_POLS; i++) {
- struct blkcg_policy *pol = blkcg_policy[i];
- struct blkg_policy_data *pd;
- if (!blkcg_policy_enabled(q, pol))
- continue;
- /* alloc per-policy data and attach it to blkg */
- pd = kzalloc_node(pol->pd_size, gfp_mask, q->node);
- if (!pd)
- goto err_free;
- blkg->pd[i] = pd;
- pd->blkg = blkg;
- /* invoke per-policy init */
- if (blkcg_policy_enabled(blkg->q, pol))
- pol->pd_init_fn(blkg);
- }
- return blkg;
- err_free:
- blkg_free(blkg);
- return NULL;
- }
- static struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg,
- struct request_queue *q)
|