diff mbox

blk-mq request allocation stalls [was: Re: [PATCH v3 0/8] dm: add request-based blk-mq support]

Message ID 54B071DC.9000307@kernel.dk (mailing list archive)
State Not Applicable, archived
Delegated to: Mike Snitzer
Headers show

Commit Message

Jens Axboe Jan. 10, 2015, 12:27 a.m. UTC
On 01/09/2015 03:25 PM, Mike Snitzer wrote:
> On Fri, Jan 09 2015 at  4:56pm -0500,
> Jens Axboe <axboe@kernel.dk> wrote:
> 
>> On 01/09/2015 02:40 PM, Mike Snitzer wrote:
>>> On Fri, Jan 09 2015 at  4:11pm -0500,
>>> Jens Axboe <axboe@kernel.dk> wrote:
>>>
>>>>
>>>> Actually, try this one instead, it should be a bit more precise than
>>>> the first.
>>>>
>>>
>>> Thanks for the test patch.
>>>
>>> I'm still seeing failures that look wrong (last_tag=127 could be edge
>>> condition not handled properly?):
>>>
>>> [   14.254632] __bt_get: values before for loop: last_tag=127, index=3
>>> [   14.255841] __bt_get: values after  for loop: last_tag=64, index=2
>>> [   14.257036]
>>> [   14.257036] bt_get: __bt_get() returned -1
>>> [   14.258051] queue_num=0, nr_tags=128, reserved_tags=0, bits_per_word=5
>>> [   14.259246] nr_free=128, nr_reserved=0
>>> [   14.259963] active_queues=0
>>>
>>> [  213.115997] __bt_get: values before for loop: last_tag=127, index=3
>>> [  213.117115] __bt_get: values after  for loop: last_tag=96, index=3
>>> [  213.118200]
>>> [  213.118200] bt_get: __bt_get() returned -1
>>> [  213.121593] queue_num=0, nr_tags=128, reserved_tags=0, bits_per_word=5
>>> [  213.123960] nr_free=128, nr_reserved=0
>>> [  213.125880] active_queues=0
>>>
>>> [  239.158079] __bt_get: values before for loop: last_tag=8, index=0
>>> [  239.160363] __bt_get: values after  for loop: last_tag=0, index=0
>>> [  239.162896]
>>> [  239.162896] bt_get: __bt_get() returned -1
>>> [  239.166284] queue_num=0, nr_tags=128, reserved_tags=0, bits_per_word=5
>>> [  239.168623] nr_free=127, nr_reserved=0
>>> [  239.170508] active_queues=0
>>
>> Thanks for testing, can you try this one?
> 
> Huh, at least now we're now seeing some nr_free=0... but the last 3
> failures below look unnecessary still.  E.g. the last_tag=127 case
> 
> [   13.895265] __bt_get: values before for loop: last_tag=59, index=1
> [   13.895265] __bt_get: values after  for loop: last_tag=32, index=1
> [   13.895266] 
> [   13.895266] bt_get: __bt_get() returned -1
> [   13.895267] queue_num=0, nr_tags=128, reserved_tags=0, bits_per_word=5
> [   13.895267] nr_free=0, nr_reserved=0
> [   13.895268] active_queues=0
> 
> [   13.895269] __bt_get: values before for loop: last_tag=0, index=0
> [   13.895270] __bt_get: values after  for loop: last_tag=0, index=0
> [   13.895270] 
> [   13.895270] bt_get: __bt_get() returned -1
> [   13.895271] queue_num=0, nr_tags=128, reserved_tags=0, bits_per_word=5
> [   13.895272] nr_free=0, nr_reserved=0
> [   13.895272] active_queues=0
> [   13.895324] __bt_get: values before for loop: last_tag=0, index=0
> [   13.895324] __bt_get: values after  for loop: last_tag=0, index=0
> [   13.895325] bt_get: __bt_get() _still_ returned -1
> [   13.895325] queue_num=0, nr_tags=128, reserved_tags=0, bits_per_word=5
> [   13.895326] nr_free=0, nr_reserved=0
> [   13.895326] active_queues=0
> 
> [   18.931425] __bt_get: values before for loop: last_tag=127, index=3
> [   18.933317] __bt_get: values after  for loop: last_tag=0, index=0
> [   18.935140] 
> [   18.935140] bt_get: __bt_get() returned -1
> [   18.936807] queue_num=0, nr_tags=128, reserved_tags=0, bits_per_word=5
> [   18.938772] nr_free=128, nr_reserved=0
> [   18.939927] active_queues=0
> 
> [  489.119597] __bt_get: values before for loop: last_tag=95, index=2
> [  489.120621] __bt_get: values after  for loop: last_tag=96, index=3
> [  489.121624]
> [  489.121624] bt_get: __bt_get() returned -1
> [  489.122532] queue_num=0, nr_tags=128, reserved_tags=0, bits_per_word=5
> [  489.123581] nr_free=128, nr_reserved=0
> [  489.124206] active_queues=0
> 
> [  494.705758] __bt_get: values before for loop: last_tag=127, index=3
> [  494.707797] __bt_get: values after  for loop: last_tag=0, index=0
> [  494.709696] 
> [  494.709696] bt_get: __bt_get() returned -1
> [  494.712459] queue_num=0, nr_tags=128, reserved_tags=0, bits_per_word=5
> [  494.714403] nr_free=128, nr_reserved=0
> [  494.715955] active_queues=0

I sent out the half-done v3, unfortunately. Can you try this? Both the
cases with substantial nr_free are at the end of an index.

If this one doesn't solve it, I'll reproduce it myself to save the
ping-pong effort :-)
diff mbox

Patch

diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
index 60c9d4a93fe4..1ce031a56080 100644
--- a/block/blk-mq-tag.c
+++ b/block/blk-mq-tag.c
@@ -142,29 +142,29 @@  static inline bool hctx_may_queue(struct blk_mq_hw_ctx *hctx,
 
 static int __bt_get_word(struct blk_align_bitmap *bm, unsigned int last_tag)
 {
-	int tag, org_last_tag, end;
-	bool wrap = last_tag != 0;
+	int tag, org_last_tag = last_tag;
 
-	org_last_tag = last_tag;
-	end = bm->depth;
-	do {
-restart:
-		tag = find_next_zero_bit(&bm->word, end, last_tag);
-		if (unlikely(tag >= end)) {
+	while (1) {
+		tag = find_next_zero_bit(&bm->word, bm->depth, last_tag);
+		if (unlikely(tag >= bm->depth)) {
 			/*
 			 * We started with an offset, start from 0 to
 			 * exhaust the map.
 			 */
-			if (wrap) {
-				wrap = false;
-				end = org_last_tag;
-				last_tag = 0;
-				goto restart;
+			if (org_last_tag) {
+				last_tag = org_last_tag = 0;
+				continue;
 			}
 			return -1;
 		}
+
+		if (!test_and_set_bit(tag, &bm->word))
+			break;
+
 		last_tag = tag + 1;
-	} while (test_and_set_bit(tag, &bm->word));
+		if (last_tag >= bm->depth - 1)
+			last_tag = 0;
+	}
 
 	return tag;
 }
@@ -199,9 +199,13 @@  static int __bt_get(struct blk_mq_hw_ctx *hctx, struct blk_mq_bitmap_tags *bt,
 			goto done;
 		}
 
-		last_tag = 0;
-		if (++index >= bt->map_nr)
+		index++;
+		last_tag = (index << bt->bits_per_word);
+
+		if (index >= bt->map_nr) {
 			index = 0;
+			last_tag = 0;
+		}
 	}
 
 	*tag_cache = 0;