aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-mq-tag.c59
-rw-r--r--block/blk-mq-tag.h7
2 files changed, 41 insertions, 25 deletions
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
index 467f3a20b355..8d526a3e02f6 100644
--- a/block/blk-mq-tag.c
+++ b/block/blk-mq-tag.c
@@ -44,7 +44,7 @@ static int __bt_get_word(struct blk_mq_bitmap *bm, unsigned int last_tag)
44{ 44{
45 int tag, org_last_tag, end; 45 int tag, org_last_tag, end;
46 46
47 org_last_tag = last_tag = TAG_TO_BIT(last_tag); 47 org_last_tag = last_tag;
48 end = bm->depth; 48 end = bm->depth;
49 do { 49 do {
50restart: 50restart:
@@ -84,12 +84,12 @@ static int __bt_get(struct blk_mq_bitmap_tags *bt, unsigned int *tag_cache)
84 int index, i, tag; 84 int index, i, tag;
85 85
86 last_tag = org_last_tag = *tag_cache; 86 last_tag = org_last_tag = *tag_cache;
87 index = TAG_TO_INDEX(last_tag); 87 index = TAG_TO_INDEX(bt, last_tag);
88 88
89 for (i = 0; i < bt->map_nr; i++) { 89 for (i = 0; i < bt->map_nr; i++) {
90 tag = __bt_get_word(&bt->map[index], last_tag); 90 tag = __bt_get_word(&bt->map[index], TAG_TO_BIT(bt, last_tag));
91 if (tag != -1) { 91 if (tag != -1) {
92 tag += index * BITS_PER_LONG; 92 tag += (index << bt->bits_per_word);
93 goto done; 93 goto done;
94 } 94 }
95 95
@@ -233,14 +233,17 @@ static struct bt_wait_state *bt_wake_ptr(struct blk_mq_bitmap_tags *bt)
233 233
234static void bt_clear_tag(struct blk_mq_bitmap_tags *bt, unsigned int tag) 234static void bt_clear_tag(struct blk_mq_bitmap_tags *bt, unsigned int tag)
235{ 235{
236 const int index = TAG_TO_INDEX(tag); 236 const int index = TAG_TO_INDEX(bt, tag);
237 struct bt_wait_state *bs; 237 struct bt_wait_state *bs;
238 238
239 clear_bit(TAG_TO_BIT(tag), &bt->map[index].word); 239 /*
240 * The unlock memory barrier need to order access to req in free
241 * path and clearing tag bit
242 */
243 clear_bit_unlock(TAG_TO_BIT(bt, tag), &bt->map[index].word);
240 244
241 bs = bt_wake_ptr(bt); 245 bs = bt_wake_ptr(bt);
242 if (bs && atomic_dec_and_test(&bs->wait_cnt)) { 246 if (bs && atomic_dec_and_test(&bs->wait_cnt)) {
243 smp_mb__after_clear_bit();
244 atomic_set(&bs->wait_cnt, bt->wake_cnt); 247 atomic_set(&bs->wait_cnt, bt->wake_cnt);
245 bt_index_inc(&bt->wake_index); 248 bt_index_inc(&bt->wake_index);
246 wake_up(&bs->wait); 249 wake_up(&bs->wait);
@@ -292,7 +295,7 @@ static void bt_for_each_free(struct blk_mq_bitmap_tags *bt,
292 bit++; 295 bit++;
293 } while (1); 296 } while (1);
294 297
295 off += BITS_PER_LONG; 298 off += (1 << bt->bits_per_word);
296 } 299 }
297} 300}
298 301
@@ -333,14 +336,31 @@ static int bt_alloc(struct blk_mq_bitmap_tags *bt, unsigned int depth,
333{ 336{
334 int i; 337 int i;
335 338
339 bt->bits_per_word = ilog2(BITS_PER_LONG);
340
336 /* 341 /*
337 * Depth can be zero for reserved tags, that's not a failure 342 * Depth can be zero for reserved tags, that's not a failure
338 * condition. 343 * condition.
339 */ 344 */
340 if (depth) { 345 if (depth) {
341 int nr, i, map_depth; 346 unsigned int nr, i, map_depth, tags_per_word;
347
348 tags_per_word = (1 << bt->bits_per_word);
349
350 /*
351 * If the tag space is small, shrink the number of tags
352 * per word so we spread over a few cachelines, at least.
353 * If less than 4 tags, just forget about it, it's not
354 * going to work optimally anyway.
355 */
356 if (depth >= 4) {
357 while (tags_per_word * 4 > depth) {
358 bt->bits_per_word--;
359 tags_per_word = (1 << bt->bits_per_word);
360 }
361 }
342 362
343 nr = ALIGN(depth, BITS_PER_LONG) / BITS_PER_LONG; 363 nr = ALIGN(depth, tags_per_word) / tags_per_word;
344 bt->map = kzalloc_node(nr * sizeof(struct blk_mq_bitmap), 364 bt->map = kzalloc_node(nr * sizeof(struct blk_mq_bitmap),
345 GFP_KERNEL, node); 365 GFP_KERNEL, node);
346 if (!bt->map) 366 if (!bt->map)
@@ -349,8 +369,8 @@ static int bt_alloc(struct blk_mq_bitmap_tags *bt, unsigned int depth,
349 bt->map_nr = nr; 369 bt->map_nr = nr;
350 map_depth = depth; 370 map_depth = depth;
351 for (i = 0; i < nr; i++) { 371 for (i = 0; i < nr; i++) {
352 bt->map[i].depth = min(map_depth, BITS_PER_LONG); 372 bt->map[i].depth = min(map_depth, tags_per_word);
353 map_depth -= BITS_PER_LONG; 373 map_depth -= tags_per_word;
354 } 374 }
355 } 375 }
356 376
@@ -397,7 +417,6 @@ enomem:
397struct blk_mq_tags *blk_mq_init_tags(unsigned int total_tags, 417struct blk_mq_tags *blk_mq_init_tags(unsigned int total_tags,
398 unsigned int reserved_tags, int node) 418 unsigned int reserved_tags, int node)
399{ 419{
400 unsigned int nr_tags, nr_cache;
401 struct blk_mq_tags *tags; 420 struct blk_mq_tags *tags;
402 421
403 if (total_tags > BLK_MQ_TAG_MAX) { 422 if (total_tags > BLK_MQ_TAG_MAX) {
@@ -409,9 +428,6 @@ struct blk_mq_tags *blk_mq_init_tags(unsigned int total_tags,
409 if (!tags) 428 if (!tags)
410 return NULL; 429 return NULL;
411 430
412 nr_tags = total_tags - reserved_tags;
413 nr_cache = nr_tags / num_online_cpus();
414
415 tags->nr_tags = total_tags; 431 tags->nr_tags = total_tags;
416 tags->nr_reserved_tags = reserved_tags; 432 tags->nr_reserved_tags = reserved_tags;
417 433
@@ -429,10 +445,7 @@ void blk_mq_tag_init_last_tag(struct blk_mq_tags *tags, unsigned int *tag)
429{ 445{
430 unsigned int depth = tags->nr_tags - tags->nr_reserved_tags; 446 unsigned int depth = tags->nr_tags - tags->nr_reserved_tags;
431 447
432 if (depth > 1) 448 *tag = prandom_u32() % depth;
433 *tag = prandom_u32() % (depth - 1);
434 else
435 *tag = 0;
436} 449}
437 450
438ssize_t blk_mq_tag_sysfs_show(struct blk_mq_tags *tags, char *page) 451ssize_t blk_mq_tag_sysfs_show(struct blk_mq_tags *tags, char *page)
@@ -443,8 +456,10 @@ ssize_t blk_mq_tag_sysfs_show(struct blk_mq_tags *tags, char *page)
443 if (!tags) 456 if (!tags)
444 return 0; 457 return 0;
445 458
446 page += sprintf(page, "nr_tags=%u, reserved_tags=%u\n", 459 page += sprintf(page, "nr_tags=%u, reserved_tags=%u, "
447 tags->nr_tags, tags->nr_reserved_tags); 460 "bits_per_word=%u\n",
461 tags->nr_tags, tags->nr_reserved_tags,
462 tags->bitmap_tags.bits_per_word);
448 463
449 free = bt_unused_tags(&tags->bitmap_tags); 464 free = bt_unused_tags(&tags->bitmap_tags);
450 res = bt_unused_tags(&tags->breserved_tags); 465 res = bt_unused_tags(&tags->breserved_tags);
diff --git a/block/blk-mq-tag.h b/block/blk-mq-tag.h
index 06d4a2f0f7a0..7aa9f0665489 100644
--- a/block/blk-mq-tag.h
+++ b/block/blk-mq-tag.h
@@ -11,8 +11,8 @@ struct bt_wait_state {
11 wait_queue_head_t wait; 11 wait_queue_head_t wait;
12} ____cacheline_aligned_in_smp; 12} ____cacheline_aligned_in_smp;
13 13
14#define TAG_TO_INDEX(tag) ((tag) / BITS_PER_LONG) 14#define TAG_TO_INDEX(bt, tag) ((tag) >> (bt)->bits_per_word)
15#define TAG_TO_BIT(tag) ((tag) & (BITS_PER_LONG - 1)) 15#define TAG_TO_BIT(bt, tag) ((tag) & ((1 << (bt)->bits_per_word) - 1))
16 16
17struct blk_mq_bitmap { 17struct blk_mq_bitmap {
18 unsigned long word; 18 unsigned long word;
@@ -22,9 +22,10 @@ struct blk_mq_bitmap {
22struct blk_mq_bitmap_tags { 22struct blk_mq_bitmap_tags {
23 unsigned int depth; 23 unsigned int depth;
24 unsigned int wake_cnt; 24 unsigned int wake_cnt;
25 unsigned int bits_per_word;
25 26
26 struct blk_mq_bitmap *map;
27 unsigned int map_nr; 27 unsigned int map_nr;
28 struct blk_mq_bitmap *map;
28 29
29 unsigned int wake_index; 30 unsigned int wake_index;
30 struct bt_wait_state *bs; 31 struct bt_wait_state *bs;