Skip to content

Commit 24391c0

Browse files
shligitaxboe
authored andcommitted
blk-mq: add tag allocation policy
This is the blk-mq part to support tag allocation policy. The default allocation policy isn't changed (though it's not a strict FIFO). The new policy is round-robin for libata. But it's a try-best implementation. If multiple tasks are competing, the tags returned will be mixed (which is unavoidable even with !mq, as requests from different tasks can be mixed in queue) Cc: Jens Axboe <axboe@fb.com> Cc: Tejun Heo <tj@kernel.org> Cc: Christoph Hellwig <hch@infradead.org> Signed-off-by: Shaohua Li <shli@fb.com> Signed-off-by: Jens Axboe <axboe@fb.com>
1 parent ee1b6f7 commit 24391c0

File tree

5 files changed

+39
-17
lines changed

5 files changed

+39
-17
lines changed

block/blk-mq-tag.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ static inline bool hctx_may_queue(struct blk_mq_hw_ctx *hctx,
140140
return atomic_read(&hctx->nr_active) < depth;
141141
}
142142

143-
static int __bt_get_word(struct blk_align_bitmap *bm, unsigned int last_tag)
143+
static int __bt_get_word(struct blk_align_bitmap *bm, unsigned int last_tag,
144+
bool nowrap)
144145
{
145146
int tag, org_last_tag = last_tag;
146147

@@ -152,7 +153,7 @@ static int __bt_get_word(struct blk_align_bitmap *bm, unsigned int last_tag)
152153
* offset to 0 in a failure case, so start from 0 to
153154
* exhaust the map.
154155
*/
155-
if (org_last_tag && last_tag) {
156+
if (org_last_tag && last_tag && !nowrap) {
156157
last_tag = org_last_tag = 0;
157158
continue;
158159
}
@@ -170,6 +171,8 @@ static int __bt_get_word(struct blk_align_bitmap *bm, unsigned int last_tag)
170171
return tag;
171172
}
172173

174+
#define BT_ALLOC_RR(tags) (tags->alloc_policy == BLK_TAG_ALLOC_RR)
175+
173176
/*
174177
* Straight forward bitmap tag implementation, where each bit is a tag
175178
* (cleared == free, and set == busy). The small twist is using per-cpu
@@ -182,7 +185,7 @@ static int __bt_get_word(struct blk_align_bitmap *bm, unsigned int last_tag)
182185
* until the map is exhausted.
183186
*/
184187
static int __bt_get(struct blk_mq_hw_ctx *hctx, struct blk_mq_bitmap_tags *bt,
185-
unsigned int *tag_cache)
188+
unsigned int *tag_cache, struct blk_mq_tags *tags)
186189
{
187190
unsigned int last_tag, org_last_tag;
188191
int index, i, tag;
@@ -194,7 +197,8 @@ static int __bt_get(struct blk_mq_hw_ctx *hctx, struct blk_mq_bitmap_tags *bt,
194197
index = TAG_TO_INDEX(bt, last_tag);
195198

196199
for (i = 0; i < bt->map_nr; i++) {
197-
tag = __bt_get_word(&bt->map[index], TAG_TO_BIT(bt, last_tag));
200+
tag = __bt_get_word(&bt->map[index], TAG_TO_BIT(bt, last_tag),
201+
BT_ALLOC_RR(tags));
198202
if (tag != -1) {
199203
tag += (index << bt->bits_per_word);
200204
goto done;
@@ -221,7 +225,7 @@ static int __bt_get(struct blk_mq_hw_ctx *hctx, struct blk_mq_bitmap_tags *bt,
221225
* up using the specific cached tag.
222226
*/
223227
done:
224-
if (tag == org_last_tag) {
228+
if (tag == org_last_tag || unlikely(BT_ALLOC_RR(tags))) {
225229
last_tag = tag + 1;
226230
if (last_tag >= bt->depth - 1)
227231
last_tag = 0;
@@ -250,13 +254,13 @@ static struct bt_wait_state *bt_wait_ptr(struct blk_mq_bitmap_tags *bt,
250254
static int bt_get(struct blk_mq_alloc_data *data,
251255
struct blk_mq_bitmap_tags *bt,
252256
struct blk_mq_hw_ctx *hctx,
253-
unsigned int *last_tag)
257+
unsigned int *last_tag, struct blk_mq_tags *tags)
254258
{
255259
struct bt_wait_state *bs;
256260
DEFINE_WAIT(wait);
257261
int tag;
258262

259-
tag = __bt_get(hctx, bt, last_tag);
263+
tag = __bt_get(hctx, bt, last_tag, tags);
260264
if (tag != -1)
261265
return tag;
262266

@@ -267,7 +271,7 @@ static int bt_get(struct blk_mq_alloc_data *data,
267271
do {
268272
prepare_to_wait(&bs->wait, &wait, TASK_UNINTERRUPTIBLE);
269273

270-
tag = __bt_get(hctx, bt, last_tag);
274+
tag = __bt_get(hctx, bt, last_tag, tags);
271275
if (tag != -1)
272276
break;
273277

@@ -282,7 +286,7 @@ static int bt_get(struct blk_mq_alloc_data *data,
282286
* Retry tag allocation after running the hardware queue,
283287
* as running the queue may also have found completions.
284288
*/
285-
tag = __bt_get(hctx, bt, last_tag);
289+
tag = __bt_get(hctx, bt, last_tag, tags);
286290
if (tag != -1)
287291
break;
288292

@@ -313,7 +317,7 @@ static unsigned int __blk_mq_get_tag(struct blk_mq_alloc_data *data)
313317
int tag;
314318

315319
tag = bt_get(data, &data->hctx->tags->bitmap_tags, data->hctx,
316-
&data->ctx->last_tag);
320+
&data->ctx->last_tag, data->hctx->tags);
317321
if (tag >= 0)
318322
return tag + data->hctx->tags->nr_reserved_tags;
319323

@@ -329,7 +333,8 @@ static unsigned int __blk_mq_get_reserved_tag(struct blk_mq_alloc_data *data)
329333
return BLK_MQ_TAG_FAIL;
330334
}
331335

332-
tag = bt_get(data, &data->hctx->tags->breserved_tags, NULL, &zero);
336+
tag = bt_get(data, &data->hctx->tags->breserved_tags, NULL, &zero,
337+
data->hctx->tags);
333338
if (tag < 0)
334339
return BLK_MQ_TAG_FAIL;
335340

@@ -401,7 +406,8 @@ void blk_mq_put_tag(struct blk_mq_hw_ctx *hctx, unsigned int tag,
401406

402407
BUG_ON(real_tag >= tags->nr_tags);
403408
bt_clear_tag(&tags->bitmap_tags, real_tag);
404-
*last_tag = real_tag;
409+
if (likely(tags->alloc_policy == BLK_TAG_ALLOC_FIFO))
410+
*last_tag = real_tag;
405411
} else {
406412
BUG_ON(tag >= tags->nr_reserved_tags);
407413
bt_clear_tag(&tags->breserved_tags, tag);
@@ -538,10 +544,12 @@ static void bt_free(struct blk_mq_bitmap_tags *bt)
538544
}
539545

540546
static struct blk_mq_tags *blk_mq_init_bitmap_tags(struct blk_mq_tags *tags,
541-
int node)
547+
int node, int alloc_policy)
542548
{
543549
unsigned int depth = tags->nr_tags - tags->nr_reserved_tags;
544550

551+
tags->alloc_policy = alloc_policy;
552+
545553
if (bt_alloc(&tags->bitmap_tags, depth, node, false))
546554
goto enomem;
547555
if (bt_alloc(&tags->breserved_tags, tags->nr_reserved_tags, node, true))
@@ -555,7 +563,8 @@ static struct blk_mq_tags *blk_mq_init_bitmap_tags(struct blk_mq_tags *tags,
555563
}
556564

557565
struct blk_mq_tags *blk_mq_init_tags(unsigned int total_tags,
558-
unsigned int reserved_tags, int node)
566+
unsigned int reserved_tags,
567+
int node, int alloc_policy)
559568
{
560569
struct blk_mq_tags *tags;
561570

@@ -571,7 +580,7 @@ struct blk_mq_tags *blk_mq_init_tags(unsigned int total_tags,
571580
tags->nr_tags = total_tags;
572581
tags->nr_reserved_tags = reserved_tags;
573582

574-
return blk_mq_init_bitmap_tags(tags, node);
583+
return blk_mq_init_bitmap_tags(tags, node, alloc_policy);
575584
}
576585

577586
void blk_mq_free_tags(struct blk_mq_tags *tags)

block/blk-mq-tag.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ struct blk_mq_tags {
4242

4343
struct request **rqs;
4444
struct list_head page_list;
45+
46+
int alloc_policy;
4547
};
4648

4749

48-
extern struct blk_mq_tags *blk_mq_init_tags(unsigned int nr_tags, unsigned int reserved_tags, int node);
50+
extern struct blk_mq_tags *blk_mq_init_tags(unsigned int nr_tags, unsigned int reserved_tags, int node, int alloc_policy);
4951
extern void blk_mq_free_tags(struct blk_mq_tags *tags);
5052

5153
extern unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data);

block/blk-mq.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1374,7 +1374,8 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set,
13741374
size_t rq_size, left;
13751375

13761376
tags = blk_mq_init_tags(set->queue_depth, set->reserved_tags,
1377-
set->numa_node);
1377+
set->numa_node,
1378+
BLK_MQ_FLAG_TO_ALLOC_POLICY(set->flags));
13781379
if (!tags)
13791380
return NULL;
13801381

drivers/scsi/scsi_lib.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2188,6 +2188,8 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost)
21882188
shost->tag_set.cmd_size = cmd_size;
21892189
shost->tag_set.numa_node = NUMA_NO_NODE;
21902190
shost->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_SG_MERGE;
2191+
shost->tag_set.flags |=
2192+
BLK_ALLOC_POLICY_TO_MQ_FLAG(shost->hostt->tag_alloc_policy);
21912193
shost->tag_set.driver_data = shost;
21922194

21932195
return blk_mq_alloc_tag_set(&shost->tag_set);

include/linux/blk-mq.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ enum {
147147
BLK_MQ_F_SG_MERGE = 1 << 2,
148148
BLK_MQ_F_SYSFS_UP = 1 << 3,
149149
BLK_MQ_F_DEFER_ISSUE = 1 << 4,
150+
BLK_MQ_F_ALLOC_POLICY_START_BIT = 8,
151+
BLK_MQ_F_ALLOC_POLICY_BITS = 1,
150152

151153
BLK_MQ_S_STOPPED = 0,
152154
BLK_MQ_S_TAG_ACTIVE = 1,
@@ -155,6 +157,12 @@ enum {
155157

156158
BLK_MQ_CPU_WORK_BATCH = 8,
157159
};
160+
#define BLK_MQ_FLAG_TO_ALLOC_POLICY(flags) \
161+
((flags >> BLK_MQ_F_ALLOC_POLICY_START_BIT) & \
162+
((1 << BLK_MQ_F_ALLOC_POLICY_BITS) - 1))
163+
#define BLK_ALLOC_POLICY_TO_MQ_FLAG(policy) \
164+
((policy & ((1 << BLK_MQ_F_ALLOC_POLICY_BITS) - 1)) \
165+
<< BLK_MQ_F_ALLOC_POLICY_START_BIT)
158166

159167
struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *);
160168
void blk_mq_finish_init(struct request_queue *q);

0 commit comments

Comments
 (0)