| 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 100static 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)
 |