All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] block: fixes for always associate blkg
@ 2018-10-20 18:56 Dennis Zhou
  2018-10-20 18:56 ` [PATCH 1/2] blkcg: fix edge case for blk_get_rl() under memory pressure Dennis Zhou
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Dennis Zhou @ 2018-10-20 18:56 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Tejun Heo, Valdis Kletnieks, kernel-team, linux-block,
	linux-kernel, Dennis Zhou

Hi everyone,

It was reported in [1] that blk_get_rl() cleanup patch was causing a
null pointer dereference. After some back and forth debugging with
Valdis, it turns out I wasn't properly handling association with
recursive calls to make_request().

Another issue was identified with the blk_get_rl() update as it is
possible under certain circumstances that a blkg cannot be allocated
when called in blk_get_rl(). This could result in the blkcg_root being
returned. However, the blkcg_root is a special case where all blkgs
share the request_queue's request_list.

The original series can be found at [2].

[1] https://lore.kernel.org/lkml/13987.1539646128@turing-police.cc.vt.edu/
[2] https://lore.kernel.org/lkml/20180911184137.35897-1-dennisszhou@gmail.com/

This patchset contains the following 2 patches:
  0001-blkcg-fix-edge-case-for-blk_get_rl-under-memory-pres.patch
  0002-blkcg-reassociate-bios-when-make_request-is-called-r.patch

0001 addresses an edge case where a blkg cannot be created and can
possibly return a blkg associated with the blkcg_root. 0002 fixes the
stale association when make_request() is called recursively.

This patchset is on top of axboe#for-4.20/block bbc152825afc.

diffstats below:

Dennis Zhou (2):
  blkcg: fix edge case for blk_get_rl() under memory pressure
  blkcg: reassociate bios when make_request() is called recursively

 block/bio.c                | 20 ++++++++++++++++++++
 block/blk-core.c           |  1 +
 include/linux/bio.h        |  3 +++
 include/linux/blk-cgroup.h |  2 +-
 4 files changed, 25 insertions(+), 1 deletion(-)

Thanks,
Dennis

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] blkcg: fix edge case for blk_get_rl() under memory pressure
  2018-10-20 18:56 [PATCH 0/2] block: fixes for always associate blkg Dennis Zhou
@ 2018-10-20 18:56 ` Dennis Zhou
  2018-10-20 18:56 ` [PATCH 2/2] blkcg: reassociate bios when make_request() is called recursively Dennis Zhou
  2018-10-20 21:40 ` [PATCH 0/2] block: fixes for always associate blkg Jens Axboe
  2 siblings, 0 replies; 4+ messages in thread
From: Dennis Zhou @ 2018-10-20 18:56 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Tejun Heo, Valdis Kletnieks, kernel-team, linux-block,
	linux-kernel, Dennis Zhou

It is possible for blkg creation to fail when in blk_get_rl(). In this
situation, the fallback logic returns the nearest created blkg. There is
however special handling for the request_list for the root blkcg. This
fixes the missing edge case from the earlier series changing
blk_get_rl().

Fixes: e2b0989954ae ("blkcg: cleanup and make blk_get_rl use blkg_lookup_create")
Signed-off-by: Dennis Zhou <dennis@kernel.org>
---
 include/linux/blk-cgroup.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index b7fd08013de2..1e76ceebeb5d 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -597,7 +597,7 @@ static inline struct request_list *blk_get_rl(struct request_queue *q,
 	if (unlikely(!blkg))
 		blkg = __blkg_lookup_create(blkcg, q);
 
-	if (!blkg_tryget(blkg))
+	if (blkg->blkcg == &blkcg_root || !blkg_tryget(blkg))
 		goto rl_use_root;
 
 	rcu_read_unlock();
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] blkcg: reassociate bios when make_request() is called recursively
  2018-10-20 18:56 [PATCH 0/2] block: fixes for always associate blkg Dennis Zhou
  2018-10-20 18:56 ` [PATCH 1/2] blkcg: fix edge case for blk_get_rl() under memory pressure Dennis Zhou
@ 2018-10-20 18:56 ` Dennis Zhou
  2018-10-20 21:40 ` [PATCH 0/2] block: fixes for always associate blkg Jens Axboe
  2 siblings, 0 replies; 4+ messages in thread
From: Dennis Zhou @ 2018-10-20 18:56 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Tejun Heo, Valdis Kletnieks, kernel-team, linux-block,
	linux-kernel, Dennis Zhou

When submitting a bio, multiple recursive calls to make_request() may
occur. This causes the initial associate done in blkcg_bio_issue_check()
to be incorrect and reference the prior request_queue. This introduces
a helper to do reassociation when make_request() is recursively called.

Fixes: a7b39b4e961c ("blkcg: always associate a bio with a blkg")
Reported-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>
Signed-off-by: Dennis Zhou <dennis@kernel.org>
Tested-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>
---
 block/bio.c         | 20 ++++++++++++++++++++
 block/blk-core.c    |  1 +
 include/linux/bio.h |  3 +++
 3 files changed, 24 insertions(+)

diff --git a/block/bio.c b/block/bio.c
index 17a8b0aa7050..bbfeb4ee2892 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -2083,6 +2083,26 @@ int bio_associate_create_blkg(struct request_queue *q, struct bio *bio)
 	return ret;
 }
 
+/**
+ * bio_reassociate_blkg - reassociate a bio with a blkg from q
+ * @q: request_queue where bio is going
+ * @bio: target bio
+ *
+ * When submitting a bio, multiple recursive calls to make_request() may occur.
+ * This causes the initial associate done in blkcg_bio_issue_check() to be
+ * incorrect and reference the prior request_queue.  This performs reassociation
+ * when this situation happens.
+ */
+int bio_reassociate_blkg(struct request_queue *q, struct bio *bio)
+{
+	if (bio->bi_blkg) {
+		blkg_put(bio->bi_blkg);
+		bio->bi_blkg = NULL;
+	}
+
+	return bio_associate_create_blkg(q, bio);
+}
+
 /**
  * bio_disassociate_task - undo bio_associate_current()
  * @bio: target bio
diff --git a/block/blk-core.c b/block/blk-core.c
index cdfabc5646da..3ed60723e242 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -2433,6 +2433,7 @@ blk_qc_t generic_make_request(struct bio *bio)
 			if (q)
 				blk_queue_exit(q);
 			q = bio->bi_disk->queue;
+			bio_reassociate_blkg(q, bio);
 			flags = 0;
 			if (bio->bi_opf & REQ_NOWAIT)
 				flags = BLK_MQ_REQ_NOWAIT;
diff --git a/include/linux/bio.h b/include/linux/bio.h
index f447b0ebb288..b47c7f716731 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -514,6 +514,7 @@ int bio_associate_blkg(struct bio *bio, struct blkcg_gq *blkg);
 int bio_associate_blkg_from_css(struct bio *bio,
 				struct cgroup_subsys_state *css);
 int bio_associate_create_blkg(struct request_queue *q, struct bio *bio);
+int bio_reassociate_blkg(struct request_queue *q, struct bio *bio);
 void bio_disassociate_task(struct bio *bio);
 void bio_clone_blkg_association(struct bio *dst, struct bio *src);
 #else	/* CONFIG_BLK_CGROUP */
@@ -522,6 +523,8 @@ static inline int bio_associate_blkg_from_css(struct bio *bio,
 { return 0; }
 static inline int bio_associate_create_blkg(struct request_queue *q,
 					    struct bio *bio) { return 0; }
+static inline int bio_reassociate_blkg(struct request_queue *q, struct bio *bio)
+{ return 0; }
 static inline void bio_disassociate_task(struct bio *bio) { }
 static inline void bio_clone_blkg_association(struct bio *dst,
 					      struct bio *src) { }
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] block: fixes for always associate blkg
  2018-10-20 18:56 [PATCH 0/2] block: fixes for always associate blkg Dennis Zhou
  2018-10-20 18:56 ` [PATCH 1/2] blkcg: fix edge case for blk_get_rl() under memory pressure Dennis Zhou
  2018-10-20 18:56 ` [PATCH 2/2] blkcg: reassociate bios when make_request() is called recursively Dennis Zhou
@ 2018-10-20 21:40 ` Jens Axboe
  2 siblings, 0 replies; 4+ messages in thread
From: Jens Axboe @ 2018-10-20 21:40 UTC (permalink / raw)
  To: Dennis Zhou
  Cc: Tejun Heo, Valdis Kletnieks, kernel-team, linux-block, linux-kernel

On 10/20/18 12:56 PM, Dennis Zhou wrote:
> Hi everyone,
> 
> It was reported in [1] that blk_get_rl() cleanup patch was causing a
> null pointer dereference. After some back and forth debugging with
> Valdis, it turns out I wasn't properly handling association with
> recursive calls to make_request().
> 
> Another issue was identified with the blk_get_rl() update as it is
> possible under certain circumstances that a blkg cannot be allocated
> when called in blk_get_rl(). This could result in the blkcg_root being
> returned. However, the blkcg_root is a special case where all blkgs
> share the request_queue's request_list.
> 
> The original series can be found at [2].
> 
> [1] https://lore.kernel.org/lkml/13987.1539646128@turing-police.cc.vt.edu/
> [2] https://lore.kernel.org/lkml/20180911184137.35897-1-dennisszhou@gmail.com/
> 
> This patchset contains the following 2 patches:
>   0001-blkcg-fix-edge-case-for-blk_get_rl-under-memory-pres.patch
>   0002-blkcg-reassociate-bios-when-make_request-is-called-r.patch
> 
> 0001 addresses an edge case where a blkg cannot be created and can
> possibly return a blkg associated with the blkcg_root. 0002 fixes the
> stale association when make_request() is called recursively.

Thanks Dennis, applied.

-- 
Jens Axboe

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-10-20 21:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-20 18:56 [PATCH 0/2] block: fixes for always associate blkg Dennis Zhou
2018-10-20 18:56 ` [PATCH 1/2] blkcg: fix edge case for blk_get_rl() under memory pressure Dennis Zhou
2018-10-20 18:56 ` [PATCH 2/2] blkcg: reassociate bios when make_request() is called recursively Dennis Zhou
2018-10-20 21:40 ` [PATCH 0/2] block: fixes for always associate blkg Jens Axboe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.