diff options
author | Dennis Zhou (Facebook) <dennisszhou@gmail.com> | 2018-09-11 14:41:28 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-09-21 20:29:05 -0600 |
commit | 07b05bcc3213ac9f8c28c9d835b4bf3d5798cc60 (patch) | |
tree | efab6cd44e334f64c1a98ae1b57a6894d9130c23 /include/linux/blk-cgroup.h | |
parent | 49f4c2dc2b5066e9211101c59cc0828e81d41614 (diff) | |
download | lwn-07b05bcc3213ac9f8c28c9d835b4bf3d5798cc60.tar.gz lwn-07b05bcc3213ac9f8c28c9d835b4bf3d5798cc60.zip |
blkcg: convert blkg_lookup_create to find closest blkg
There are several scenarios where blkg_lookup_create can fail. Examples
include the blkcg dying, request_queue is dying, or simply being OOM. At
the end of the day, most handle this by simply falling back to the
q->root_blkg and calling it a day.
This patch implements the notion of closest blkg. During
blkg_lookup_create, if it fails to create, return the closest blkg
found or the q->root_blkg. blkg_try_get_closest is introduced and used
during association so a bio is always attached to a blkg.
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 'include/linux/blk-cgroup.h')
-rw-r--r-- | include/linux/blk-cgroup.h | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h index cc0f238530f6..1fbff1bbb651 100644 --- a/include/linux/blk-cgroup.h +++ b/include/linux/blk-cgroup.h @@ -549,6 +549,20 @@ static inline struct blkcg_gq *blkg_try_get(struct blkcg_gq *blkg) return NULL; } +/** + * blkg_try_get_closest - try and get a blkg ref on the closet blkg + * @blkg: blkg to get + * + * This walks up the blkg tree to find the closest non-dying blkg and returns + * the blkg that it did association with as it may not be the passed in blkg. + */ +static inline struct blkcg_gq *blkg_try_get_closest(struct blkcg_gq *blkg) +{ + while (!atomic_inc_not_zero(&blkg->refcnt)) + blkg = blkg->parent; + + return blkg; +} void __blkg_release_rcu(struct rcu_head *rcu); |