Skip to content

Commit

Permalink
blkio: Implement dynamic io controlling policy registration
Browse files Browse the repository at this point in the history
o One of the goals of block IO controller is that it should be able to
  support mulitple io control policies, some of which be operational at
  higher level in storage hierarchy.

o To begin with, we had one io controlling policy implemented by CFQ, and
  I hard coded the CFQ functions called by blkio. This created issues when
  CFQ is compiled as module.

o This patch implements a basic dynamic io controlling policy registration
  functionality in blkio. This is similar to elevator functionality where
  ioschedulers register the functions dynamically.

o Now in future, when more IO controlling policies are implemented, these
  can dynakically register with block IO controller.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
  • Loading branch information
Vivek Goyal authored and Jens Axboe committed Dec 4, 2009
1 parent 9d6a986 commit 3e25206
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 12 deletions.
36 changes: 32 additions & 4 deletions block/blk-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
#include <linux/kdev_t.h>
#include <linux/module.h>
#include "blk-cgroup.h"
#include "cfq-iosched.h"

static DEFINE_SPINLOCK(blkio_list_lock);
static LIST_HEAD(blkio_list);

struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT };
EXPORT_SYMBOL_GPL(blkio_root_cgroup);
Expand Down Expand Up @@ -138,15 +140,21 @@ blkiocg_weight_write(struct cgroup *cgroup, struct cftype *cftype, u64 val)
struct blkio_cgroup *blkcg;
struct blkio_group *blkg;
struct hlist_node *n;
struct blkio_policy_type *blkiop;

if (val < BLKIO_WEIGHT_MIN || val > BLKIO_WEIGHT_MAX)
return -EINVAL;

blkcg = cgroup_to_blkio_cgroup(cgroup);
spin_lock_irq(&blkcg->lock);
blkcg->weight = (unsigned int)val;
hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node)
cfq_update_blkio_group_weight(blkg, blkcg->weight);
hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) {
spin_lock(&blkio_list_lock);
list_for_each_entry(blkiop, &blkio_list, list)
blkiop->ops.blkio_update_group_weight_fn(blkg,
blkcg->weight);
spin_unlock(&blkio_list_lock);
}
spin_unlock_irq(&blkcg->lock);
return 0;
}
Expand Down Expand Up @@ -224,6 +232,7 @@ static void blkiocg_destroy(struct cgroup_subsys *subsys, struct cgroup *cgroup)
unsigned long flags;
struct blkio_group *blkg;
void *key;
struct blkio_policy_type *blkiop;

rcu_read_lock();
remove_entry:
Expand All @@ -249,7 +258,10 @@ static void blkiocg_destroy(struct cgroup_subsys *subsys, struct cgroup *cgroup)
* we have more policies in place, we need some dynamic registration
* of callback function.
*/
cfq_unlink_blkio_group(key, blkg);
spin_lock(&blkio_list_lock);
list_for_each_entry(blkiop, &blkio_list, list)
blkiop->ops.blkio_unlink_group_fn(key, blkg);
spin_unlock(&blkio_list_lock);
goto remove_entry;
done:
free_css_id(&blkio_subsys, &blkcg->css);
Expand Down Expand Up @@ -330,3 +342,19 @@ struct cgroup_subsys blkio_subsys = {
.subsys_id = blkio_subsys_id,
.use_id = 1,
};

void blkio_policy_register(struct blkio_policy_type *blkiop)
{
spin_lock(&blkio_list_lock);
list_add_tail(&blkiop->list, &blkio_list);
spin_unlock(&blkio_list_lock);
}
EXPORT_SYMBOL_GPL(blkio_policy_register);

void blkio_policy_unregister(struct blkio_policy_type *blkiop)
{
spin_lock(&blkio_list_lock);
list_del_init(&blkiop->list);
spin_unlock(&blkio_list_lock);
}
EXPORT_SYMBOL_GPL(blkio_policy_unregister);
24 changes: 24 additions & 0 deletions block/blk-cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,35 @@ struct blkio_group {
extern bool blkiocg_css_tryget(struct blkio_cgroup *blkcg);
extern void blkiocg_css_put(struct blkio_cgroup *blkcg);

typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg);
typedef void (blkio_update_group_weight_fn) (struct blkio_group *blkg,
unsigned int weight);

struct blkio_policy_ops {
blkio_unlink_group_fn *blkio_unlink_group_fn;
blkio_update_group_weight_fn *blkio_update_group_weight_fn;
};

struct blkio_policy_type {
struct list_head list;
struct blkio_policy_ops ops;
};

/* Blkio controller policy registration */
extern void blkio_policy_register(struct blkio_policy_type *);
extern void blkio_policy_unregister(struct blkio_policy_type *);

#else

struct blkio_group {
};

struct blkio_policy_type {
};

static inline void blkio_policy_register(struct blkio_policy_type *blkiop) { }
static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { }

#endif

#define BLKIO_WEIGHT_MIN 100
Expand Down
14 changes: 13 additions & 1 deletion block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include <linux/ioprio.h>
#include <linux/blktrace_api.h>
#include "blk-cgroup.h"
#include "cfq-iosched.h"

/*
* tunables
Expand Down Expand Up @@ -3855,6 +3854,17 @@ static struct elevator_type iosched_cfq = {
.elevator_owner = THIS_MODULE,
};

#ifdef CONFIG_CFQ_GROUP_IOSCHED
static struct blkio_policy_type blkio_policy_cfq = {
.ops = {
.blkio_unlink_group_fn = cfq_unlink_blkio_group,
.blkio_update_group_weight_fn = cfq_update_blkio_group_weight,
},
};
#else
static struct blkio_policy_type blkio_policy_cfq;
#endif

static int __init cfq_init(void)
{
/*
Expand All @@ -3869,13 +3879,15 @@ static int __init cfq_init(void)
return -ENOMEM;

elv_register(&iosched_cfq);
blkio_policy_register(&blkio_policy_cfq);

return 0;
}

static void __exit cfq_exit(void)
{
DECLARE_COMPLETION_ONSTACK(all_gone);
blkio_policy_unregister(&blkio_policy_cfq);
elv_unregister(&iosched_cfq);
ioc_gone = &all_gone;
/* ioc_gone's update must be visible before reading ioc_count */
Expand Down
7 changes: 0 additions & 7 deletions block/cfq-iosched.h

This file was deleted.

0 comments on commit 3e25206

Please sign in to comment.