[PATCH 3/5] bfq: Simplify bfq_put_cooperator()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



All calls to bfq_setup_merge() are followed by bfq_merge_bfqqs() so
there should be no chance for chaining several queue merges. And if
chained queue merges were possible, then bfq_put_cooperator() would drop
cooperator references without clearing corresponding bfqq->new_bfqq
pointers causing possible use-after-free issues. Fix these problems by
making bfq_put_cooperator() drop only the immediate bfqq->new_bfqq
reference.

CC: stable@xxxxxxxxxxxxxxx
Fixes: 36eca8948323 ("block, bfq: add Early Queue Merge (EQM)")
Signed-off-by: Jan Kara <jack@xxxxxxx>
---
 block/bfq-iosched.c | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 0da47f2ca781..654191c6face 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -5184,22 +5184,16 @@ static void bfq_put_stable_ref(struct bfq_queue *bfqq)
 	bfq_put_queue(bfqq);
 }
 
+
+/*
+ * If this queue was scheduled to merge with another queue, be
+ * sure to drop the reference taken on that queue.
+ */
 static void bfq_put_cooperator(struct bfq_queue *bfqq)
 {
-	struct bfq_queue *__bfqq, *next;
-
-	/*
-	 * If this queue was scheduled to merge with another queue, be
-	 * sure to drop the reference taken on that queue (and others in
-	 * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs.
-	 */
-	__bfqq = bfqq->new_bfqq;
-	while (__bfqq) {
-		if (__bfqq == bfqq)
-			break;
-		next = __bfqq->new_bfqq;
-		bfq_put_queue(__bfqq);
-		__bfqq = next;
+	if (bfqq->new_bfqq) {
+		bfq_put_queue(bfqq->new_bfqq);
+		bfqq->new_bfqq = NULL;
 	}
 }
 
-- 
2.31.1




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux