summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/bio.c62
-rw-r--r--include/linux/blk-cgroup.h52
-rw-r--r--include/linux/cgroup.h2
-rw-r--r--kernel/cgroup/cgroup.c48
4 files changed, 81 insertions, 83 deletions
diff --git a/block/bio.c b/block/bio.c
index 71cfe3720ea7..c39251e69447 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1978,18 +1978,30 @@ int bio_associate_blkg(struct bio *bio, struct blkcg_gq *blkg)
1978 return 0; 1978 return 0;
1979} 1979}
1980 1980
1981/**
1982 * __bio_associate_blkg_from_css - internal blkg association function
1983 *
1984 * This in the core association function that all association paths rely on.
1985 * A blkg reference is taken which is released upon freeing of the bio.
1986 */
1981static int __bio_associate_blkg_from_css(struct bio *bio, 1987static int __bio_associate_blkg_from_css(struct bio *bio,
1982 struct cgroup_subsys_state *css) 1988 struct cgroup_subsys_state *css)
1983{ 1989{
1990 struct request_queue *q = bio->bi_disk->queue;
1984 struct blkcg_gq *blkg; 1991 struct blkcg_gq *blkg;
1992 int ret;
1985 1993
1986 rcu_read_lock(); 1994 rcu_read_lock();
1987 1995
1988 blkg = blkg_lookup_create(css_to_blkcg(css), bio->bi_disk->queue); 1996 if (!css || !css->parent)
1997 blkg = q->root_blkg;
1998 else
1999 blkg = blkg_lookup_create(css_to_blkcg(css), q);
1989 2000
1990 rcu_read_unlock(); 2001 ret = bio_associate_blkg(bio, blkg);
1991 2002
1992 return bio_associate_blkg(bio, blkg); 2003 rcu_read_unlock();
2004 return ret;
1993} 2005}
1994 2006
1995/** 2007/**
@@ -1998,13 +2010,14 @@ static int __bio_associate_blkg_from_css(struct bio *bio,
1998 * @css: target css 2010 * @css: target css
1999 * 2011 *
2000 * Associate @bio with the blkg found by combining the css's blkg and the 2012 * Associate @bio with the blkg found by combining the css's blkg and the
2001 * request_queue of the @bio. This takes a reference on the css that will 2013 * request_queue of the @bio. This falls back to the queue's root_blkg if
2002 * be put upon freeing of @bio. 2014 * the association fails with the css.
2003 */ 2015 */
2004int bio_associate_blkg_from_css(struct bio *bio, 2016int bio_associate_blkg_from_css(struct bio *bio,
2005 struct cgroup_subsys_state *css) 2017 struct cgroup_subsys_state *css)
2006{ 2018{
2007 css_get(css); 2019 if (unlikely(bio->bi_blkg))
2020 return -EBUSY;
2008 return __bio_associate_blkg_from_css(bio, css); 2021 return __bio_associate_blkg_from_css(bio, css);
2009} 2022}
2010EXPORT_SYMBOL_GPL(bio_associate_blkg_from_css); 2023EXPORT_SYMBOL_GPL(bio_associate_blkg_from_css);
@@ -2016,22 +2029,29 @@ EXPORT_SYMBOL_GPL(bio_associate_blkg_from_css);
2016 * @page: the page to lookup the blkcg from 2029 * @page: the page to lookup the blkcg from
2017 * 2030 *
2018 * Associate @bio with the blkg from @page's owning memcg and the respective 2031 * Associate @bio with the blkg from @page's owning memcg and the respective
2019 * request_queue. This works like every other associate function wrt 2032 * request_queue. If cgroup_e_css returns NULL, fall back to the queue's
2020 * references. 2033 * root_blkg.
2021 * 2034 *
2022 * Note: this must be called after bio has an associated device. 2035 * Note: this must be called after bio has an associated device.
2023 */ 2036 */
2024int bio_associate_blkg_from_page(struct bio *bio, struct page *page) 2037int bio_associate_blkg_from_page(struct bio *bio, struct page *page)
2025{ 2038{
2026 struct cgroup_subsys_state *css; 2039 struct cgroup_subsys_state *css;
2040 int ret;
2027 2041
2028 if (unlikely(bio->bi_blkg)) 2042 if (unlikely(bio->bi_blkg))
2029 return -EBUSY; 2043 return -EBUSY;
2030 if (!page->mem_cgroup) 2044 if (!page->mem_cgroup)
2031 return 0; 2045 return 0;
2032 css = cgroup_get_e_css(page->mem_cgroup->css.cgroup, &io_cgrp_subsys);
2033 2046
2034 return __bio_associate_blkg_from_css(bio, css); 2047 rcu_read_lock();
2048
2049 css = cgroup_e_css(page->mem_cgroup->css.cgroup, &io_cgrp_subsys);
2050
2051 ret = __bio_associate_blkg_from_css(bio, css);
2052
2053 rcu_read_unlock();
2054 return ret;
2035} 2055}
2036#endif /* CONFIG_MEMCG */ 2056#endif /* CONFIG_MEMCG */
2037 2057
@@ -2041,12 +2061,12 @@ int bio_associate_blkg_from_page(struct bio *bio, struct page *page)
2041 * @bio: target bio 2061 * @bio: target bio
2042 * 2062 *
2043 * Associate @bio with the blkg found from the bio's css and the request_queue. 2063 * Associate @bio with the blkg found from the bio's css and the request_queue.
2044 * If one is not found, bio_lookup_blkg creates the blkg. 2064 * If one is not found, bio_lookup_blkg creates the blkg. This falls back to
2065 * the queue's root_blkg if association fails.
2045 */ 2066 */
2046int bio_associate_create_blkg(struct request_queue *q, struct bio *bio) 2067int bio_associate_create_blkg(struct request_queue *q, struct bio *bio)
2047{ 2068{
2048 struct blkcg *blkcg; 2069 struct cgroup_subsys_state *css;
2049 struct blkcg_gq *blkg;
2050 int ret = 0; 2070 int ret = 0;
2051 2071
2052 /* someone has already associated this bio with a blkg */ 2072 /* someone has already associated this bio with a blkg */
@@ -2055,15 +2075,9 @@ int bio_associate_create_blkg(struct request_queue *q, struct bio *bio)
2055 2075
2056 rcu_read_lock(); 2076 rcu_read_lock();
2057 2077
2058 blkcg = css_to_blkcg(blkcg_get_css()); 2078 css = blkcg_css();
2059 2079
2060 if (!blkcg->css.parent) { 2080 ret = __bio_associate_blkg_from_css(bio, css);
2061 ret = bio_associate_blkg(bio, q->root_blkg);
2062 } else {
2063 blkg = blkg_lookup_create(blkcg, q);
2064
2065 ret = bio_associate_blkg(bio, blkg);
2066 }
2067 2081
2068 rcu_read_unlock(); 2082 rcu_read_unlock();
2069 return ret; 2083 return ret;
@@ -2080,8 +2094,6 @@ void bio_disassociate_task(struct bio *bio)
2080 bio->bi_ioc = NULL; 2094 bio->bi_ioc = NULL;
2081 } 2095 }
2082 if (bio->bi_blkg) { 2096 if (bio->bi_blkg) {
2083 /* a ref is always taken on css */
2084 css_put(&bio_blkcg(bio)->css);
2085 blkg_put(bio->bi_blkg); 2097 blkg_put(bio->bi_blkg);
2086 bio->bi_blkg = NULL; 2098 bio->bi_blkg = NULL;
2087 } 2099 }
@@ -2094,10 +2106,8 @@ void bio_disassociate_task(struct bio *bio)
2094 */ 2106 */
2095void bio_clone_blkg_association(struct bio *dst, struct bio *src) 2107void bio_clone_blkg_association(struct bio *dst, struct bio *src)
2096{ 2108{
2097 if (src->bi_blkg) { 2109 if (src->bi_blkg)
2098 css_get(&bio_blkcg(src)->css);
2099 bio_associate_blkg(dst, src->bi_blkg); 2110 bio_associate_blkg(dst, src->bi_blkg);
2100 }
2101} 2111}
2102EXPORT_SYMBOL_GPL(bio_clone_blkg_association); 2112EXPORT_SYMBOL_GPL(bio_clone_blkg_association);
2103#endif /* CONFIG_BLK_CGROUP */ 2113#endif /* CONFIG_BLK_CGROUP */
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index c41cfcc2b4d8..2951ea3541b1 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -249,47 +249,6 @@ static inline struct cgroup_subsys_state *blkcg_css(void)
249 return task_css(current, io_cgrp_id); 249 return task_css(current, io_cgrp_id);
250} 250}
251 251
252/**
253 * blkcg_get_css - find and get a reference to the css
254 *
255 * Find the css associated with either the kthread or the current task.
256 * This takes a reference on the blkcg which will need to be managed by the
257 * caller.
258 */
259static inline struct cgroup_subsys_state *blkcg_get_css(void)
260{
261 struct cgroup_subsys_state *css;
262
263 rcu_read_lock();
264
265 css = kthread_blkcg();
266 if (css) {
267 css_get(css);
268 } else {
269 /*
270 * This is a bit complicated. It is possible task_css is seeing
271 * an old css pointer here. This is caused by the current
272 * thread migrating away from this cgroup and this cgroup dying.
273 * css_tryget() will fail when trying to take a ref on a cgroup
274 * that's ref count has hit 0.
275 *
276 * Therefore, if it does fail, this means current must have
277 * been swapped away already and this is waiting for it to
278 * propagate on the polling cpu. Hence the use of cpu_relax().
279 */
280 while (true) {
281 css = task_css(current, io_cgrp_id);
282 if (likely(css_tryget(css)))
283 break;
284 cpu_relax();
285 }
286 }
287
288 rcu_read_unlock();
289
290 return css;
291}
292
293static inline struct blkcg *css_to_blkcg(struct cgroup_subsys_state *css) 252static inline struct blkcg *css_to_blkcg(struct cgroup_subsys_state *css)
294{ 253{
295 return css ? container_of(css, struct blkcg, css) : NULL; 254 return css ? container_of(css, struct blkcg, css) : NULL;
@@ -628,10 +587,8 @@ static inline struct request_list *blk_get_rl(struct request_queue *q,
628 rcu_read_lock(); 587 rcu_read_lock();
629 588
630 blkcg = bio_blkcg(bio); 589 blkcg = bio_blkcg(bio);
631 if (blkcg) 590 if (!blkcg)
632 css_get(&blkcg->css); 591 blkcg = css_to_blkcg(blkcg_css());
633 else
634 blkcg = css_to_blkcg(blkcg_get_css());
635 592
636 /* bypass blkg lookup and use @q->root_rl directly for root */ 593 /* bypass blkg lookup and use @q->root_rl directly for root */
637 if (blkcg == &blkcg_root) 594 if (blkcg == &blkcg_root)
@@ -646,7 +603,8 @@ static inline struct request_list *blk_get_rl(struct request_queue *q,
646 if (unlikely(!blkg)) 603 if (unlikely(!blkg))
647 goto root_rl; 604 goto root_rl;
648 605
649 blkg_get(blkg); 606 if (!blkg_try_get(blkg))
607 goto root_rl;
650 rcu_read_unlock(); 608 rcu_read_unlock();
651 return &blkg->rl; 609 return &blkg->rl;
652root_rl: 610root_rl:
@@ -663,8 +621,6 @@ root_rl:
663 */ 621 */
664static inline void blk_put_rl(struct request_list *rl) 622static inline void blk_put_rl(struct request_list *rl)
665{ 623{
666 /* an additional ref is always taken for rl */
667 css_put(&rl->blkg->blkcg->css);
668 if (rl->blkg->blkcg != &blkcg_root) 624 if (rl->blkg->blkcg != &blkcg_root)
669 blkg_put(rl->blkg); 625 blkg_put(rl->blkg);
670} 626}
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 32c553556bbd..b8bcbdeb2eac 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -93,6 +93,8 @@ extern struct css_set init_css_set;
93 93
94bool css_has_online_children(struct cgroup_subsys_state *css); 94bool css_has_online_children(struct cgroup_subsys_state *css);
95struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss); 95struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss);
96struct cgroup_subsys_state *cgroup_e_css(struct cgroup *cgroup,
97 struct cgroup_subsys *ss);
96struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgroup, 98struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgroup,
97 struct cgroup_subsys *ss); 99 struct cgroup_subsys *ss);
98struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry, 100struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry,
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index aae10baf1902..48fb22e49467 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -492,7 +492,7 @@ static struct cgroup_subsys_state *cgroup_tryget_css(struct cgroup *cgrp,
492} 492}
493 493
494/** 494/**
495 * cgroup_e_css - obtain a cgroup's effective css for the specified subsystem 495 * cgroup_e_css_by_mask - obtain a cgroup's effective css for the specified ss
496 * @cgrp: the cgroup of interest 496 * @cgrp: the cgroup of interest
497 * @ss: the subsystem of interest (%NULL returns @cgrp->self) 497 * @ss: the subsystem of interest (%NULL returns @cgrp->self)
498 * 498 *
@@ -501,8 +501,8 @@ static struct cgroup_subsys_state *cgroup_tryget_css(struct cgroup *cgrp,
501 * enabled. If @ss is associated with the hierarchy @cgrp is on, this 501 * enabled. If @ss is associated with the hierarchy @cgrp is on, this
502 * function is guaranteed to return non-NULL css. 502 * function is guaranteed to return non-NULL css.
503 */ 503 */
504static struct cgroup_subsys_state *cgroup_e_css(struct cgroup *cgrp, 504static struct cgroup_subsys_state *cgroup_e_css_by_mask(struct cgroup *cgrp,
505 struct cgroup_subsys *ss) 505 struct cgroup_subsys *ss)
506{ 506{
507 lockdep_assert_held(&cgroup_mutex); 507 lockdep_assert_held(&cgroup_mutex);
508 508
@@ -523,6 +523,35 @@ static struct cgroup_subsys_state *cgroup_e_css(struct cgroup *cgrp,
523} 523}
524 524
525/** 525/**
526 * cgroup_e_css - obtain a cgroup's effective css for the specified subsystem
527 * @cgrp: the cgroup of interest
528 * @ss: the subsystem of interest
529 *
530 * Find and get the effective css of @cgrp for @ss. The effective css is
531 * defined as the matching css of the nearest ancestor including self which
532 * has @ss enabled. If @ss is not mounted on the hierarchy @cgrp is on,
533 * the root css is returned, so this function always returns a valid css.
534 *
535 * The returned css is not guaranteed to be online, and therefore it is the
536 * callers responsiblity to tryget a reference for it.
537 */
538struct cgroup_subsys_state *cgroup_e_css(struct cgroup *cgrp,
539 struct cgroup_subsys *ss)
540{
541 struct cgroup_subsys_state *css;
542
543 do {
544 css = cgroup_css(cgrp, ss);
545
546 if (css)
547 return css;
548 cgrp = cgroup_parent(cgrp);
549 } while (cgrp);
550
551 return init_css_set.subsys[ss->id];
552}
553
554/**
526 * cgroup_get_e_css - get a cgroup's effective css for the specified subsystem 555 * cgroup_get_e_css - get a cgroup's effective css for the specified subsystem
527 * @cgrp: the cgroup of interest 556 * @cgrp: the cgroup of interest
528 * @ss: the subsystem of interest 557 * @ss: the subsystem of interest
@@ -604,10 +633,11 @@ EXPORT_SYMBOL_GPL(of_css);
604 * 633 *
605 * Should be called under cgroup_[tree_]mutex. 634 * Should be called under cgroup_[tree_]mutex.
606 */ 635 */
607#define for_each_e_css(css, ssid, cgrp) \ 636#define for_each_e_css(css, ssid, cgrp) \
608 for ((ssid) = 0; (ssid) < CGROUP_SUBSYS_COUNT; (ssid)++) \ 637 for ((ssid) = 0; (ssid) < CGROUP_SUBSYS_COUNT; (ssid)++) \
609 if (!((css) = cgroup_e_css(cgrp, cgroup_subsys[(ssid)]))) \ 638 if (!((css) = cgroup_e_css_by_mask(cgrp, \
610 ; \ 639 cgroup_subsys[(ssid)]))) \
640 ; \
611 else 641 else
612 642
613/** 643/**
@@ -1006,7 +1036,7 @@ static struct css_set *find_existing_css_set(struct css_set *old_cset,
1006 * @ss is in this hierarchy, so we want the 1036 * @ss is in this hierarchy, so we want the
1007 * effective css from @cgrp. 1037 * effective css from @cgrp.
1008 */ 1038 */
1009 template[i] = cgroup_e_css(cgrp, ss); 1039 template[i] = cgroup_e_css_by_mask(cgrp, ss);
1010 } else { 1040 } else {
1011 /* 1041 /*
1012 * @ss is not in this hierarchy, so we don't want 1042 * @ss is not in this hierarchy, so we don't want
@@ -3019,7 +3049,7 @@ static int cgroup_apply_control(struct cgroup *cgrp)
3019 return ret; 3049 return ret;
3020 3050
3021 /* 3051 /*
3022 * At this point, cgroup_e_css() results reflect the new csses 3052 * At this point, cgroup_e_css_by_mask() results reflect the new csses
3023 * making the following cgroup_update_dfl_csses() properly update 3053 * making the following cgroup_update_dfl_csses() properly update
3024 * css associations of all tasks in the subtree. 3054 * css associations of all tasks in the subtree.
3025 */ 3055 */