Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 309211
b: refs/heads/master
c: 0381411
h: refs/heads/master
i:
  309209: 11f87af
  309207: a9e32d5
v: v3
  • Loading branch information
Tejun Heo authored and Jens Axboe committed Mar 6, 2012
1 parent 2cc2d81 commit d4d4255
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 112 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 923adde1be1df57cebd80c563058e503376645e8
refs/heads/master: 0381411e4b1a52cee134eb73750e5e3cc1155d09
86 changes: 67 additions & 19 deletions trunk/block/blk-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,70 @@ void blkiocg_update_io_merged_stats(struct blkio_group *blkg, bool direction,
}
EXPORT_SYMBOL_GPL(blkiocg_update_io_merged_stats);

/**
* blkg_free - free a blkg
* @blkg: blkg to free
*
* Free @blkg which may be partially allocated.
*/
static void blkg_free(struct blkio_group *blkg)
{
if (blkg) {
free_percpu(blkg->stats_cpu);
kfree(blkg->pd);
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
* @pol: policy the new blkg is associated with
*
* Allocate a new blkg assocating @blkcg and @q for @pol.
*
* FIXME: Should be called with queue locked but currently isn't due to
* percpu stat breakage.
*/
static struct blkio_group *blkg_alloc(struct blkio_cgroup *blkcg,
struct request_queue *q,
struct blkio_policy_type *pol)
{
struct blkio_group *blkg;

/* alloc and init base part */
blkg = kzalloc_node(sizeof(*blkg), GFP_ATOMIC, q->node);
if (!blkg)
return NULL;

spin_lock_init(&blkg->stats_lock);
rcu_assign_pointer(blkg->q, q);
blkg->blkcg = blkcg;
blkg->plid = pol->plid;
cgroup_path(blkcg->css.cgroup, blkg->path, sizeof(blkg->path));

/* alloc per-policy data */
blkg->pd = kzalloc_node(sizeof(*blkg->pd) + pol->pdata_size, GFP_ATOMIC,
q->node);
if (!blkg->pd) {
blkg_free(blkg);
return NULL;
}

/* broken, read comment in the callsite */
blkg->stats_cpu = alloc_percpu(struct blkio_group_stats_cpu);
if (!blkg->stats_cpu) {
blkg_free(blkg);
return NULL;
}

/* attach pd to blkg and invoke per-policy init */
blkg->pd->blkg = blkg;
pol->ops.blkio_init_group_fn(blkg);
return blkg;
}

struct blkio_group *blkg_lookup_create(struct blkio_cgroup *blkcg,
struct request_queue *q,
enum blkio_policy_id plid,
Expand Down Expand Up @@ -463,19 +527,7 @@ struct blkio_group *blkg_lookup_create(struct blkio_cgroup *blkcg,
spin_unlock_irq(q->queue_lock);
rcu_read_unlock();

new_blkg = pol->ops.blkio_alloc_group_fn(q, blkcg);
if (new_blkg) {
new_blkg->stats_cpu = alloc_percpu(struct blkio_group_stats_cpu);

spin_lock_init(&new_blkg->stats_lock);
rcu_assign_pointer(new_blkg->q, q);
new_blkg->blkcg = blkcg;
new_blkg->plid = plid;
cgroup_path(blkcg->css.cgroup, new_blkg->path,
sizeof(new_blkg->path));
} else {
css_put(&blkcg->css);
}
new_blkg = blkg_alloc(blkcg, q, pol);

rcu_read_lock();
spin_lock_irq(q->queue_lock);
Expand All @@ -492,7 +544,7 @@ struct blkio_group *blkg_lookup_create(struct blkio_cgroup *blkcg,
goto out;

/* did alloc fail? */
if (unlikely(!new_blkg || !new_blkg->stats_cpu)) {
if (unlikely(!new_blkg)) {
blkg = ERR_PTR(-ENOMEM);
goto out;
}
Expand All @@ -504,11 +556,7 @@ struct blkio_group *blkg_lookup_create(struct blkio_cgroup *blkcg,
pol->ops.blkio_link_group_fn(q, blkg);
spin_unlock(&blkcg->lock);
out:
if (new_blkg) {
free_percpu(new_blkg->stats_cpu);
kfree(new_blkg);
css_put(&blkcg->css);
}
blkg_free(new_blkg);
return blkg;
}
EXPORT_SYMBOL_GPL(blkg_lookup_create);
Expand Down
53 changes: 50 additions & 3 deletions trunk/block/blk-cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,15 @@ struct blkio_group_conf {
u64 bps[2];
};

/* per-blkg per-policy data */
struct blkg_policy_data {
/* the blkg this per-policy data belongs to */
struct blkio_group *blkg;

/* pol->pdata_size bytes of private data used by policy impl */
char pdata[] __aligned(__alignof__(unsigned long long));
};

struct blkio_group {
/* Pointer to the associated request_queue, RCU protected */
struct request_queue __rcu *q;
Expand All @@ -177,10 +186,11 @@ struct blkio_group {
struct blkio_group_stats stats;
/* Per cpu stats pointer */
struct blkio_group_stats_cpu __percpu *stats_cpu;

struct blkg_policy_data *pd;
};

typedef struct blkio_group *(blkio_alloc_group_fn)(struct request_queue *q,
struct blkio_cgroup *blkcg);
typedef void (blkio_init_group_fn)(struct blkio_group *blkg);
typedef void (blkio_link_group_fn)(struct request_queue *q,
struct blkio_group *blkg);
typedef void (blkio_unlink_group_fn)(struct request_queue *q,
Expand All @@ -198,7 +208,7 @@ typedef void (blkio_update_group_write_iops_fn)(struct request_queue *q,
struct blkio_group *blkg, unsigned int write_iops);

struct blkio_policy_ops {
blkio_alloc_group_fn *blkio_alloc_group_fn;
blkio_init_group_fn *blkio_init_group_fn;
blkio_link_group_fn *blkio_link_group_fn;
blkio_unlink_group_fn *blkio_unlink_group_fn;
blkio_clear_queue_fn *blkio_clear_queue_fn;
Expand All @@ -213,6 +223,7 @@ struct blkio_policy_type {
struct list_head list;
struct blkio_policy_ops ops;
enum blkio_policy_id plid;
size_t pdata_size; /* policy specific private data size */
};

extern int blkcg_init_queue(struct request_queue *q);
Expand All @@ -224,6 +235,38 @@ extern void blkio_policy_register(struct blkio_policy_type *);
extern void blkio_policy_unregister(struct blkio_policy_type *);
extern void blkg_destroy_all(struct request_queue *q);

/**
* blkg_to_pdata - get policy private data
* @blkg: blkg of interest
* @pol: policy of interest
*
* Return pointer to private data associated with the @blkg-@pol pair.
*/
static inline void *blkg_to_pdata(struct blkio_group *blkg,
struct blkio_policy_type *pol)
{
return blkg ? blkg->pd->pdata : NULL;
}

/**
* pdata_to_blkg - get blkg associated with policy private data
* @pdata: policy private data of interest
* @pol: policy @pdata is for
*
* @pdata is policy private data for @pol. Determine the blkg it's
* associated with.
*/
static inline struct blkio_group *pdata_to_blkg(void *pdata,
struct blkio_policy_type *pol)
{
if (pdata) {
struct blkg_policy_data *pd =
container_of(pdata, struct blkg_policy_data, pdata);
return pd->blkg;
}
return NULL;
}

static inline char *blkg_path(struct blkio_group *blkg)
{
return blkg->path;
Expand All @@ -244,6 +287,10 @@ static inline void blkio_policy_register(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_to_pdata(struct blkio_group *blkg,
struct blkio_policy_type *pol) { return NULL; }
static inline struct blkio_group *pdata_to_blkg(void *pdata,
struct blkio_policy_type *pol) { return NULL; }
static inline char *blkg_path(struct blkio_group *blkg) { return NULL; }

#endif
Expand Down
Loading

0 comments on commit d4d4255

Please sign in to comment.