summaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorDennis Zhou (Facebook) <dennisszhou@gmail.com>2018-09-11 14:41:34 -0400
committerJens Axboe <axboe@kernel.dk>2018-09-21 22:29:15 -0400
commitf0fcb3ec89f37167810e660b0595d9a6155d9807 (patch)
treedd230c9477e3b316863a589639280965efcbf429 /block
parentc839e7a03f92bafd71fd145b470dcdc7f43f2d4c (diff)
blkcg: remove additional reference to the css
The previous patch in this series removed carrying around a pointer to the css in blkg. However, the blkg association logic still relied on taking a reference on the css to ensure we wouldn't fail in getting a reference for the blkg. Here the implicit dependency on the css is removed. The association continues to rely on the tryget logic walking up the blkg tree. This streamlines the three ways that association can happen: normal, swap, and writeback. Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Dennis Zhou <dennisszhou@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r--block/bio.c62
1 files changed, 36 insertions, 26 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 */