提交 8bd435b3 编写于 作者: T Tejun Heo 提交者: Jens Axboe

blkcg: remove static policy ID enums

Remove BLKIO_POLICY_* enums and let blkio_policy_register() allocate
@pol->plid dynamically on registration.  The maximum number of blkcg
policies which can be registered at the same time is defined by
BLKCG_MAX_POLS constant added to include/linux/blkdev.h.

Note that blkio_policy_register() now may fail.  Policy init functions
updated accordingly and unnecessary ifdefs removed from cfq_init().
Signed-off-by: NTejun Heo <tj@kernel.org>
Cc: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: NJens Axboe <axboe@kernel.dk>
上级 ec399347
...@@ -31,7 +31,7 @@ static LIST_HEAD(all_q_list); ...@@ -31,7 +31,7 @@ static LIST_HEAD(all_q_list);
struct blkio_cgroup blkio_root_cgroup = { .cfq_weight = 2 * CFQ_WEIGHT_DEFAULT }; struct blkio_cgroup blkio_root_cgroup = { .cfq_weight = 2 * CFQ_WEIGHT_DEFAULT };
EXPORT_SYMBOL_GPL(blkio_root_cgroup); EXPORT_SYMBOL_GPL(blkio_root_cgroup);
static struct blkio_policy_type *blkio_policy[BLKIO_NR_POLICIES]; static struct blkio_policy_type *blkio_policy[BLKCG_MAX_POLS];
struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup) struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup)
{ {
...@@ -67,7 +67,7 @@ static void blkg_free(struct blkio_group *blkg) ...@@ -67,7 +67,7 @@ static void blkg_free(struct blkio_group *blkg)
if (!blkg) if (!blkg)
return; return;
for (i = 0; i < BLKIO_NR_POLICIES; i++) { for (i = 0; i < BLKCG_MAX_POLS; i++) {
struct blkio_policy_type *pol = blkio_policy[i]; struct blkio_policy_type *pol = blkio_policy[i];
struct blkg_policy_data *pd = blkg->pd[i]; struct blkg_policy_data *pd = blkg->pd[i];
...@@ -107,7 +107,7 @@ static struct blkio_group *blkg_alloc(struct blkio_cgroup *blkcg, ...@@ -107,7 +107,7 @@ static struct blkio_group *blkg_alloc(struct blkio_cgroup *blkcg,
blkg->refcnt = 1; blkg->refcnt = 1;
cgroup_path(blkcg->css.cgroup, blkg->path, sizeof(blkg->path)); cgroup_path(blkcg->css.cgroup, blkg->path, sizeof(blkg->path));
for (i = 0; i < BLKIO_NR_POLICIES; i++) { for (i = 0; i < BLKCG_MAX_POLS; i++) {
struct blkio_policy_type *pol = blkio_policy[i]; struct blkio_policy_type *pol = blkio_policy[i];
struct blkg_policy_data *pd; struct blkg_policy_data *pd;
...@@ -127,7 +127,7 @@ static struct blkio_group *blkg_alloc(struct blkio_cgroup *blkcg, ...@@ -127,7 +127,7 @@ static struct blkio_group *blkg_alloc(struct blkio_cgroup *blkcg,
} }
/* invoke per-policy init */ /* invoke per-policy init */
for (i = 0; i < BLKIO_NR_POLICIES; i++) { for (i = 0; i < BLKCG_MAX_POLS; i++) {
struct blkio_policy_type *pol = blkio_policy[i]; struct blkio_policy_type *pol = blkio_policy[i];
if (pol) if (pol)
...@@ -320,7 +320,7 @@ blkiocg_reset_stats(struct cgroup *cgroup, struct cftype *cftype, u64 val) ...@@ -320,7 +320,7 @@ blkiocg_reset_stats(struct cgroup *cgroup, struct cftype *cftype, u64 val)
* anyway. If you get hit by a race, retry. * anyway. If you get hit by a race, retry.
*/ */
hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) { hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) {
for (i = 0; i < BLKIO_NR_POLICIES; i++) { for (i = 0; i < BLKCG_MAX_POLS; i++) {
struct blkio_policy_type *pol = blkio_policy[i]; struct blkio_policy_type *pol = blkio_policy[i];
if (pol && pol->ops.blkio_reset_group_stats_fn) if (pol && pol->ops.blkio_reset_group_stats_fn)
...@@ -729,46 +729,75 @@ struct cgroup_subsys blkio_subsys = { ...@@ -729,46 +729,75 @@ struct cgroup_subsys blkio_subsys = {
}; };
EXPORT_SYMBOL_GPL(blkio_subsys); EXPORT_SYMBOL_GPL(blkio_subsys);
void blkio_policy_register(struct blkio_policy_type *blkiop) /**
* blkio_policy_register - register a blkcg policy
* @blkiop: blkcg policy to register
*
* Register @blkiop with blkcg core. Might sleep and @blkiop may be
* modified on successful registration. Returns 0 on success and -errno on
* failure.
*/
int blkio_policy_register(struct blkio_policy_type *blkiop)
{ {
struct request_queue *q; struct request_queue *q;
int i, ret;
mutex_lock(&blkcg_pol_mutex); mutex_lock(&blkcg_pol_mutex);
blkcg_bypass_start(); /* find an empty slot */
ret = -ENOSPC;
for (i = 0; i < BLKCG_MAX_POLS; i++)
if (!blkio_policy[i])
break;
if (i >= BLKCG_MAX_POLS)
goto out_unlock;
BUG_ON(blkio_policy[blkiop->plid]); /* register and update blkgs */
blkio_policy[blkiop->plid] = blkiop; blkiop->plid = i;
blkio_policy[i] = blkiop;
blkcg_bypass_start();
list_for_each_entry(q, &all_q_list, all_q_node) list_for_each_entry(q, &all_q_list, all_q_node)
update_root_blkg_pd(q, blkiop); update_root_blkg_pd(q, blkiop);
blkcg_bypass_end(); blkcg_bypass_end();
/* everything is in place, add intf files for the new policy */
if (blkiop->cftypes) if (blkiop->cftypes)
WARN_ON(cgroup_add_cftypes(&blkio_subsys, blkiop->cftypes)); WARN_ON(cgroup_add_cftypes(&blkio_subsys, blkiop->cftypes));
ret = 0;
out_unlock:
mutex_unlock(&blkcg_pol_mutex); mutex_unlock(&blkcg_pol_mutex);
return ret;
} }
EXPORT_SYMBOL_GPL(blkio_policy_register); EXPORT_SYMBOL_GPL(blkio_policy_register);
/**
* blkiop_policy_unregister - unregister a blkcg policy
* @blkiop: blkcg policy to unregister
*
* Undo blkio_policy_register(@blkiop). Might sleep.
*/
void blkio_policy_unregister(struct blkio_policy_type *blkiop) void blkio_policy_unregister(struct blkio_policy_type *blkiop)
{ {
struct request_queue *q; struct request_queue *q;
mutex_lock(&blkcg_pol_mutex); mutex_lock(&blkcg_pol_mutex);
if (WARN_ON(blkio_policy[blkiop->plid] != blkiop))
goto out_unlock;
/* kill the intf files first */
if (blkiop->cftypes) if (blkiop->cftypes)
cgroup_rm_cftypes(&blkio_subsys, blkiop->cftypes); cgroup_rm_cftypes(&blkio_subsys, blkiop->cftypes);
blkcg_bypass_start(); /* unregister and update blkgs */
BUG_ON(blkio_policy[blkiop->plid] != blkiop);
blkio_policy[blkiop->plid] = NULL; blkio_policy[blkiop->plid] = NULL;
blkcg_bypass_start();
list_for_each_entry(q, &all_q_list, all_q_node) list_for_each_entry(q, &all_q_list, all_q_node)
update_root_blkg_pd(q, blkiop); update_root_blkg_pd(q, blkiop);
blkcg_bypass_end(); blkcg_bypass_end();
out_unlock:
mutex_unlock(&blkcg_pol_mutex); mutex_unlock(&blkcg_pol_mutex);
} }
EXPORT_SYMBOL_GPL(blkio_policy_unregister); EXPORT_SYMBOL_GPL(blkio_policy_unregister);
...@@ -17,13 +17,6 @@ ...@@ -17,13 +17,6 @@
#include <linux/u64_stats_sync.h> #include <linux/u64_stats_sync.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
enum blkio_policy_id {
BLKIO_POLICY_PROP = 0, /* Proportional Bandwidth division */
BLKIO_POLICY_THROTL, /* Throttling */
BLKIO_NR_POLICIES,
};
/* Max limits for throttle policy */ /* Max limits for throttle policy */
#define THROTL_IOPS_MAX UINT_MAX #define THROTL_IOPS_MAX UINT_MAX
...@@ -86,7 +79,7 @@ struct blkio_group { ...@@ -86,7 +79,7 @@ struct blkio_group {
/* reference count */ /* reference count */
int refcnt; int refcnt;
struct blkg_policy_data *pd[BLKIO_NR_POLICIES]; struct blkg_policy_data *pd[BLKCG_MAX_POLS];
struct rcu_head rcu_head; struct rcu_head rcu_head;
}; };
...@@ -103,7 +96,7 @@ struct blkio_policy_ops { ...@@ -103,7 +96,7 @@ struct blkio_policy_ops {
struct blkio_policy_type { struct blkio_policy_type {
struct blkio_policy_ops ops; struct blkio_policy_ops ops;
enum blkio_policy_id plid; int plid;
size_t pdata_size; /* policy specific private data size */ size_t pdata_size; /* policy specific private data size */
struct cftype *cftypes; /* cgroup files for the policy */ struct cftype *cftypes; /* cgroup files for the policy */
}; };
...@@ -113,7 +106,7 @@ extern void blkcg_drain_queue(struct request_queue *q); ...@@ -113,7 +106,7 @@ extern void blkcg_drain_queue(struct request_queue *q);
extern void blkcg_exit_queue(struct request_queue *q); extern void blkcg_exit_queue(struct request_queue *q);
/* Blkio controller policy registration */ /* Blkio controller policy registration */
extern void blkio_policy_register(struct blkio_policy_type *); extern int blkio_policy_register(struct blkio_policy_type *);
extern void blkio_policy_unregister(struct blkio_policy_type *); extern void blkio_policy_unregister(struct blkio_policy_type *);
extern void blkg_destroy_all(struct request_queue *q, bool destroy_root); extern void blkg_destroy_all(struct request_queue *q, bool destroy_root);
extern void update_root_blkg_pd(struct request_queue *q, extern void update_root_blkg_pd(struct request_queue *q,
...@@ -329,7 +322,7 @@ struct blkio_policy_type { ...@@ -329,7 +322,7 @@ struct blkio_policy_type {
static inline int blkcg_init_queue(struct request_queue *q) { return 0; } static inline int blkcg_init_queue(struct request_queue *q) { return 0; }
static inline void blkcg_drain_queue(struct request_queue *q) { } static inline void blkcg_drain_queue(struct request_queue *q) { }
static inline void blkcg_exit_queue(struct request_queue *q) { } static inline void blkcg_exit_queue(struct request_queue *q) { }
static inline void blkio_policy_register(struct blkio_policy_type *blkiop) { } static inline int blkio_policy_register(struct blkio_policy_type *blkiop) { return 0; }
static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { } static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { }
static inline void blkg_destroy_all(struct request_queue *q, static inline void blkg_destroy_all(struct request_queue *q,
bool destory_root) { } bool destory_root) { }
......
...@@ -1089,7 +1089,6 @@ static struct blkio_policy_type blkio_policy_throtl = { ...@@ -1089,7 +1089,6 @@ static struct blkio_policy_type blkio_policy_throtl = {
.blkio_exit_group_fn = throtl_exit_blkio_group, .blkio_exit_group_fn = throtl_exit_blkio_group,
.blkio_reset_group_stats_fn = throtl_reset_group_stats, .blkio_reset_group_stats_fn = throtl_reset_group_stats,
}, },
.plid = BLKIO_POLICY_THROTL,
.pdata_size = sizeof(struct throtl_grp), .pdata_size = sizeof(struct throtl_grp),
.cftypes = throtl_files, .cftypes = throtl_files,
}; };
...@@ -1271,8 +1270,7 @@ static int __init throtl_init(void) ...@@ -1271,8 +1270,7 @@ static int __init throtl_init(void)
if (!kthrotld_workqueue) if (!kthrotld_workqueue)
panic("Failed to create kthrotld\n"); panic("Failed to create kthrotld\n");
blkio_policy_register(&blkio_policy_throtl); return blkio_policy_register(&blkio_policy_throtl);
return 0;
} }
module_init(throtl_init); module_init(throtl_init);
...@@ -4157,7 +4157,6 @@ static struct blkio_policy_type blkio_policy_cfq = { ...@@ -4157,7 +4157,6 @@ static struct blkio_policy_type blkio_policy_cfq = {
.blkio_init_group_fn = cfq_init_blkio_group, .blkio_init_group_fn = cfq_init_blkio_group,
.blkio_reset_group_stats_fn = cfqg_stats_reset, .blkio_reset_group_stats_fn = cfqg_stats_reset,
}, },
.plid = BLKIO_POLICY_PROP,
.pdata_size = sizeof(struct cfq_group), .pdata_size = sizeof(struct cfq_group),
.cftypes = cfq_blkcg_files, .cftypes = cfq_blkcg_files,
}; };
...@@ -4181,27 +4180,31 @@ static int __init cfq_init(void) ...@@ -4181,27 +4180,31 @@ static int __init cfq_init(void)
#else #else
cfq_group_idle = 0; cfq_group_idle = 0;
#endif #endif
ret = blkio_policy_register(&blkio_policy_cfq);
if (ret)
return ret;
cfq_pool = KMEM_CACHE(cfq_queue, 0); cfq_pool = KMEM_CACHE(cfq_queue, 0);
if (!cfq_pool) if (!cfq_pool)
return -ENOMEM; goto err_pol_unreg;
ret = elv_register(&iosched_cfq); ret = elv_register(&iosched_cfq);
if (ret) { if (ret)
kmem_cache_destroy(cfq_pool); goto err_free_pool;
return ret;
}
#ifdef CONFIG_CFQ_GROUP_IOSCHED
blkio_policy_register(&blkio_policy_cfq);
#endif
return 0; return 0;
err_free_pool:
kmem_cache_destroy(cfq_pool);
err_pol_unreg:
blkio_policy_unregister(&blkio_policy_cfq);
return ret;
} }
static void __exit cfq_exit(void) static void __exit cfq_exit(void)
{ {
#ifdef CONFIG_CFQ_GROUP_IOSCHED
blkio_policy_unregister(&blkio_policy_cfq); blkio_policy_unregister(&blkio_policy_cfq);
#endif
elv_unregister(&iosched_cfq); elv_unregister(&iosched_cfq);
kmem_cache_destroy(cfq_pool); kmem_cache_destroy(cfq_pool);
} }
......
...@@ -35,6 +35,12 @@ struct bsg_job; ...@@ -35,6 +35,12 @@ struct bsg_job;
#define BLKDEV_MIN_RQ 4 #define BLKDEV_MIN_RQ 4
#define BLKDEV_MAX_RQ 128 /* Default maximum */ #define BLKDEV_MAX_RQ 128 /* Default maximum */
/*
* Maximum number of blkcg policies allowed to be registered concurrently.
* Defined here to simplify include dependency.
*/
#define BLKCG_MAX_POLS 2
struct request; struct request;
typedef void (rq_end_io_fn)(struct request *, int); typedef void (rq_end_io_fn)(struct request *, int);
...@@ -363,7 +369,6 @@ struct request_queue { ...@@ -363,7 +369,6 @@ struct request_queue {
struct list_head icq_list; struct list_head icq_list;
#ifdef CONFIG_BLK_CGROUP #ifdef CONFIG_BLK_CGROUP
/* XXX: array size hardcoded to avoid include dependency (temporary) */
struct list_head blkg_list; struct list_head blkg_list;
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册