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 22:29:05 -0400 |
commit | 07b05bcc3213ac9f8c28c9d835b4bf3d5798cc60 (patch) | |
tree | efab6cd44e334f64c1a98ae1b57a6894d9130c23 /block/blk-cgroup.c | |
parent | 49f4c2dc2b5066e9211101c59cc0828e81d41614 (diff) |
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 'block/blk-cgroup.c')
-rw-r--r-- | block/blk-cgroup.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index cd0d97bed83d..e9e3a955f61a 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -268,9 +268,8 @@ err_free_blkg: | |||
268 | * that all non-root blkg's have access to the parent blkg. This function | 268 | * that all non-root blkg's have access to the parent blkg. This function |
269 | * should be called under RCU read lock and @q->queue_lock. | 269 | * should be called under RCU read lock and @q->queue_lock. |
270 | * | 270 | * |
271 | * Returns pointer to the looked up or created blkg on success, ERR_PTR() | 271 | * Returns the blkg or the closest blkg if blkg_create fails as it walks |
272 | * value on error. If @q is dead, returns ERR_PTR(-EINVAL). If @q is not | 272 | * down from root. |
273 | * dead and bypassing, returns ERR_PTR(-EBUSY). | ||
274 | */ | 273 | */ |
275 | struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg, | 274 | struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg, |
276 | struct request_queue *q) | 275 | struct request_queue *q) |
@@ -285,7 +284,7 @@ struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg, | |||
285 | * we shouldn't allow anything to go through for a bypassing queue. | 284 | * we shouldn't allow anything to go through for a bypassing queue. |
286 | */ | 285 | */ |
287 | if (unlikely(blk_queue_bypass(q))) | 286 | if (unlikely(blk_queue_bypass(q))) |
288 | return ERR_PTR(blk_queue_dying(q) ? -ENODEV : -EBUSY); | 287 | return q->root_blkg; |
289 | 288 | ||
290 | blkg = __blkg_lookup(blkcg, q, true); | 289 | blkg = __blkg_lookup(blkcg, q, true); |
291 | if (blkg) | 290 | if (blkg) |
@@ -293,19 +292,29 @@ struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg, | |||
293 | 292 | ||
294 | /* | 293 | /* |
295 | * Create blkgs walking down from blkcg_root to @blkcg, so that all | 294 | * Create blkgs walking down from blkcg_root to @blkcg, so that all |
296 | * non-root blkgs have access to their parents. | 295 | * non-root blkgs have access to their parents. Returns the closest |
296 | * blkg to the intended blkg should blkg_create() fail. | ||
297 | */ | 297 | */ |
298 | while (true) { | 298 | while (true) { |
299 | struct blkcg *pos = blkcg; | 299 | struct blkcg *pos = blkcg; |
300 | struct blkcg *parent = blkcg_parent(blkcg); | 300 | struct blkcg *parent = blkcg_parent(blkcg); |
301 | 301 | struct blkcg_gq *ret_blkg = q->root_blkg; | |
302 | while (parent && !__blkg_lookup(parent, q, false)) { | 302 | |
303 | while (parent) { | ||
304 | blkg = __blkg_lookup(parent, q, false); | ||
305 | if (blkg) { | ||
306 | /* remember closest blkg */ | ||
307 | ret_blkg = blkg; | ||
308 | break; | ||
309 | } | ||
303 | pos = parent; | 310 | pos = parent; |
304 | parent = blkcg_parent(parent); | 311 | parent = blkcg_parent(parent); |
305 | } | 312 | } |
306 | 313 | ||
307 | blkg = blkg_create(pos, q, NULL); | 314 | blkg = blkg_create(pos, q, NULL); |
308 | if (pos == blkcg || IS_ERR(blkg)) | 315 | if (IS_ERR(blkg)) |
316 | return ret_blkg; | ||
317 | if (pos == blkcg) | ||
309 | return blkg; | 318 | return blkg; |
310 | } | 319 | } |
311 | } | 320 | } |