From: Tejun Heo Date: Sun, 1 Apr 2012 19:30:01 +0000 (-0700) Subject: Merge branch 'for-3.5' of ../cgroup into block/for-3.5/core-merged X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=959d851caa48829eb85cb85aa949fd6b4c5d5bc6;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git Merge branch 'for-3.5' of ../cgroup into block/for-3.5/core-merged cgroup/for-3.5 contains the following changes which blk-cgroup needs to proceed with the on-going cleanup. * Dynamic addition and removal of cftypes to make config/stat file handling modular for policies. * cgroup removal update to not wait for css references to drain to fix blkcg removal hang caused by cfq caching cfqgs. Pull in cgroup/for-3.5 into block/for-3.5/core. This causes the following conflicts in block/blk-cgroup.c. * 761b3ef50e "cgroup: remove cgroup_subsys argument from callbacks" conflicts with blkiocg_pre_destroy() addition and blkiocg_attach() removal. Resolved by removing @subsys from all subsys methods. * 676f7c8f84 "cgroup: relocate cftype and cgroup_subsys definitions in controllers" conflicts with ->pre_destroy() and ->attach() updates and removal of modular config. Resolved by dropping forward declarations of the methods and applying updates to the relocated blkio_subsys. * 4baf6e3325 "cgroup: convert all non-memcg controllers to the new cftype interface" builds upon the previous item. Resolved by adding ->base_cftypes to the relocated blkio_subsys. Signed-off-by: Tejun Heo --- 959d851caa48829eb85cb85aa949fd6b4c5d5bc6 diff --cc block/blk-cgroup.c index aa54c4110f54,126c341955de..4fdeb46b4436 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@@ -41,34 -28,60 +41,14 @@@ static DECLARE_DELAYED_WORK(blkio_stat_ struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT }; EXPORT_SYMBOL_GPL(blkio_root_cgroup); +static struct blkio_policy_type *blkio_policy[BLKIO_NR_POLICIES]; + - static struct cgroup_subsys_state *blkiocg_create(struct cgroup_subsys *, - struct cgroup *); - static int blkiocg_can_attach(struct cgroup_subsys *, struct cgroup *, - struct cgroup_taskset *); - static int blkiocg_pre_destroy(struct cgroup_subsys *, struct cgroup *); - static void blkiocg_destroy(struct cgroup_subsys *, struct cgroup *); - static int blkiocg_populate(struct cgroup_subsys *, struct cgroup *); - /* for encoding cft->private value on file */ #define BLKIOFILE_PRIVATE(x, val) (((x) << 16) | (val)) /* What policy owns the file, proportional or throttle */ #define BLKIOFILE_POLICY(val) (((val) >> 16) & 0xffff) #define BLKIOFILE_ATTR(val) ((val) & 0xffff) - struct cgroup_subsys blkio_subsys = { - .name = "blkio", - .create = blkiocg_create, - .can_attach = blkiocg_can_attach, - .pre_destroy = blkiocg_pre_destroy, - .destroy = blkiocg_destroy, - .populate = blkiocg_populate, - .subsys_id = blkio_subsys_id, - .module = THIS_MODULE, - }; - EXPORT_SYMBOL_GPL(blkio_subsys); -static inline void blkio_policy_insert_node(struct blkio_cgroup *blkcg, - struct blkio_policy_node *pn) -{ - list_add(&pn->node, &blkcg->policy_list); -} - -static inline bool cftype_blkg_same_policy(struct cftype *cft, - struct blkio_group *blkg) -{ - enum blkio_policy_id plid = BLKIOFILE_POLICY(cft->private); - - if (blkg->plid == plid) - return 1; - - return 0; -} - -/* Determines if policy node matches cgroup file being accessed */ -static inline bool pn_matches_cftype(struct cftype *cft, - struct blkio_policy_node *pn) -{ - enum blkio_policy_id plid = BLKIOFILE_POLICY(cft->private); - int fileid = BLKIOFILE_ATTR(cft->private); - - return (plid == pn->plid && fileid == pn->fileid); -} - -/* Must be called with blkcg->lock held */ -static inline void blkio_policy_delete_node(struct blkio_policy_node *pn) -{ - list_del(&pn->node); -} - -/* Must be called with blkcg->lock held */ -static struct blkio_policy_node * -blkio_policy_search_node(const struct blkio_cgroup *blkcg, dev_t dev, - enum blkio_policy_id plid, int fileid) -{ - struct blkio_policy_node *pn; - - list_for_each_entry(pn, &blkcg->policy_list, node) { - if (pn->dev == dev && pn->plid == plid && pn->fileid == fileid) - return pn; - } - - return NULL; -} -- struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup) { return container_of(cgroup_subsys_state(cgroup, blkio_subsys_id), @@@ -1563,64 -1515,61 +1543,56 @@@ struct cftype blkio_files[] = .read_map = blkiocg_file_read_map, }, #endif + { } /* terminate */ }; - static int blkiocg_populate(struct cgroup_subsys *subsys, struct cgroup *cgroup) - { - return cgroup_add_files(cgroup, subsys, blkio_files, - ARRAY_SIZE(blkio_files)); - } - -static void blkiocg_destroy(struct cgroup *cgroup) +/** + * blkiocg_pre_destroy - cgroup pre_destroy callback - * @subsys: cgroup subsys + * @cgroup: cgroup of interest + * + * This function is called when @cgroup is about to go away and responsible + * for shooting down all blkgs associated with @cgroup. blkgs should be + * removed while holding both q and blkcg locks. As blkcg lock is nested + * inside q lock, this function performs reverse double lock dancing. + * + * This is the blkcg counterpart of ioc_release_fn(). + */ - static int blkiocg_pre_destroy(struct cgroup_subsys *subsys, - struct cgroup *cgroup) ++static int blkiocg_pre_destroy(struct cgroup *cgroup) { struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup); - unsigned long flags; - struct blkio_group *blkg; - void *key; - struct blkio_policy_type *blkiop; - struct blkio_policy_node *pn, *pntmp; - rcu_read_lock(); - do { - spin_lock_irqsave(&blkcg->lock, flags); + spin_lock_irq(&blkcg->lock); - if (hlist_empty(&blkcg->blkg_list)) { - spin_unlock_irqrestore(&blkcg->lock, flags); - break; + while (!hlist_empty(&blkcg->blkg_list)) { + struct blkio_group *blkg = hlist_entry(blkcg->blkg_list.first, + struct blkio_group, blkcg_node); + struct request_queue *q = blkg->q; + + if (spin_trylock(q->queue_lock)) { + blkg_destroy(blkg); + spin_unlock(q->queue_lock); + } else { + spin_unlock_irq(&blkcg->lock); + cpu_relax(); + spin_lock_irq(&blkcg->lock); } + } - 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. - */ - spin_lock(&blkio_list_lock); - list_for_each_entry(blkiop, &blkio_list, list) { - if (blkiop->plid != blkg->plid) - continue; - blkiop->ops.blkio_unlink_group_fn(key, blkg); - } - spin_unlock(&blkio_list_lock); - } while (1); + spin_unlock_irq(&blkcg->lock); + return 0; +} - static void blkiocg_destroy(struct cgroup_subsys *subsys, struct cgroup *cgroup) - list_for_each_entry_safe(pn, pntmp, &blkcg->policy_list, node) { - blkio_policy_delete_node(pn); - kfree(pn); - } ++static void blkiocg_destroy(struct cgroup *cgroup) +{ + struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup); - free_css_id(&blkio_subsys, &blkcg->css); - rcu_read_unlock(); if (blkcg != &blkio_root_cgroup) kfree(blkcg); } - static struct cgroup_subsys_state * - blkiocg_create(struct cgroup_subsys *subsys, struct cgroup *cgroup) + static struct cgroup_subsys_state *blkiocg_create(struct cgroup *cgroup) { + static atomic64_t id_seq = ATOMIC64_INIT(0); struct blkio_cgroup *blkcg; struct cgroup *parent = cgroup->parent; @@@ -1739,32 -1631,27 +1710,44 @@@ static void blkcg_bypass_start(void } } +static void blkcg_bypass_end(void) + __releases(&all_q_mutex) +{ + struct request_queue *q; + + list_for_each_entry(q, &all_q_list, all_q_node) + blk_queue_bypass_end(q); + + mutex_unlock(&all_q_mutex); +} + + struct cgroup_subsys blkio_subsys = { + .name = "blkio", + .create = blkiocg_create, + .can_attach = blkiocg_can_attach, - .attach = blkiocg_attach, ++ .pre_destroy = blkiocg_pre_destroy, + .destroy = blkiocg_destroy, -#ifdef CONFIG_BLK_CGROUP - /* note: blkio_subsys_id is otherwise defined in blk-cgroup.h */ + .subsys_id = blkio_subsys_id, -#endif + .base_cftypes = blkio_files, - .use_id = 1, + .module = THIS_MODULE, + }; + EXPORT_SYMBOL_GPL(blkio_subsys); + void blkio_policy_register(struct blkio_policy_type *blkiop) { + struct request_queue *q; + + blkcg_bypass_start(); spin_lock(&blkio_list_lock); + + BUG_ON(blkio_policy[blkiop->plid]); + blkio_policy[blkiop->plid] = blkiop; list_add_tail(&blkiop->list, &blkio_list); + spin_unlock(&blkio_list_lock); + list_for_each_entry(q, &all_q_list, all_q_node) + update_root_blkg_pd(q, blkiop->plid); + blkcg_bypass_end(); } EXPORT_SYMBOL_GPL(blkio_policy_register); diff --cc fs/bio.c index 142214b80039,e453924036e9..4ef7bd4cd48f --- a/fs/bio.c +++ b/fs/bio.c @@@ -23,10 -22,9 +23,10 @@@ #include #include #include - #include + #include #include #include +#include #include /* for struct sg_iovec */ #include