mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
blkio: Take care of cgroup deletion and cfq group reference counting
o One can choose to change elevator or delete a cgroup. Implement group reference counting so that both elevator exit and cgroup deletion can take place gracefully. Signed-off-by: Vivek Goyal <[email protected]> Signed-off-by: Nauman Rafique <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
This commit is contained in:
parent
25fb5169d4
commit
b1c3576961
3 changed files with 160 additions and 2 deletions
|
|
@ -13,6 +13,8 @@
|
|||
#include <linux/ioprio.h>
|
||||
#include "blk-cgroup.h"
|
||||
|
||||
extern void cfq_unlink_blkio_group(void *, struct blkio_group *);
|
||||
|
||||
struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT };
|
||||
|
||||
struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup)
|
||||
|
|
@ -28,14 +30,43 @@ void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
|
|||
|
||||
spin_lock_irqsave(&blkcg->lock, flags);
|
||||
rcu_assign_pointer(blkg->key, key);
|
||||
blkg->blkcg_id = css_id(&blkcg->css);
|
||||
hlist_add_head_rcu(&blkg->blkcg_node, &blkcg->blkg_list);
|
||||
spin_unlock_irqrestore(&blkcg->lock, flags);
|
||||
}
|
||||
|
||||
static void __blkiocg_del_blkio_group(struct blkio_group *blkg)
|
||||
{
|
||||
hlist_del_init_rcu(&blkg->blkcg_node);
|
||||
blkg->blkcg_id = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns 0 if blkio_group was still on cgroup list. Otherwise returns 1
|
||||
* indicating that blk_group was unhashed by the time we got to it.
|
||||
*/
|
||||
int blkiocg_del_blkio_group(struct blkio_group *blkg)
|
||||
{
|
||||
/* Implemented later */
|
||||
return 0;
|
||||
struct blkio_cgroup *blkcg;
|
||||
unsigned long flags;
|
||||
struct cgroup_subsys_state *css;
|
||||
int ret = 1;
|
||||
|
||||
rcu_read_lock();
|
||||
css = css_lookup(&blkio_subsys, blkg->blkcg_id);
|
||||
if (!css)
|
||||
goto out;
|
||||
|
||||
blkcg = container_of(css, struct blkio_cgroup, css);
|
||||
spin_lock_irqsave(&blkcg->lock, flags);
|
||||
if (!hlist_unhashed(&blkg->blkcg_node)) {
|
||||
__blkiocg_del_blkio_group(blkg);
|
||||
ret = 0;
|
||||
}
|
||||
spin_unlock_irqrestore(&blkcg->lock, flags);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* called under rcu_read_lock(). */
|
||||
|
|
@ -97,8 +128,39 @@ static int blkiocg_populate(struct cgroup_subsys *subsys, struct cgroup *cgroup)
|
|||
static void blkiocg_destroy(struct cgroup_subsys *subsys, struct cgroup *cgroup)
|
||||
{
|
||||
struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup);
|
||||
unsigned long flags;
|
||||
struct blkio_group *blkg;
|
||||
void *key;
|
||||
|
||||
rcu_read_lock();
|
||||
remove_entry:
|
||||
spin_lock_irqsave(&blkcg->lock, flags);
|
||||
|
||||
if (hlist_empty(&blkcg->blkg_list)) {
|
||||
spin_unlock_irqrestore(&blkcg->lock, flags);
|
||||
goto done;
|
||||
}
|
||||
|
||||
blkg = hlist_entry(blkcg->blkg_list.first, struct blkio_group,
|
||||
blkcg_node);
|
||||
key = rcu_dereference(blkg->key);
|
||||
__blkiocg_del_blkio_group(blkg);
|
||||
|
||||
spin_unlock_irqrestore(&blkcg->lock, flags);
|
||||
|
||||
/*
|
||||
* This blkio_group is being unlinked as associated cgroup is going
|
||||
* away. Let all the IO controlling policies know about this event.
|
||||
*
|
||||
* Currently this is static call to one io controlling policy. Once
|
||||
* we have more policies in place, we need some dynamic registration
|
||||
* of callback function.
|
||||
*/
|
||||
cfq_unlink_blkio_group(key, blkg);
|
||||
goto remove_entry;
|
||||
done:
|
||||
free_css_id(&blkio_subsys, &blkcg->css);
|
||||
rcu_read_unlock();
|
||||
kfree(blkcg);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue