blk-mq: add blk_mq_all_tag_iter
Add a new blk_mq_all_tag_iter function to iterate over all allocated scheduler tags and driver tags. This is more flexible than the existing blk_mq_all_tag_busy_iter function as it allows the callers to do whatever they want on allocated request instead of being limited to started requests. It will be used to implement draining allocated requests on specified hctx in this patchset. [hch: switch from the two booleans to a more readable flags field and consolidate the tags iter functions] Signed-off-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Daniel Wagner <dwagner@suse.de> Reviewed-by: Bart van Assche <bvanassche@acm.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Родитель
600c3b0cea
Коммит
602380d28e
|
@ -256,14 +256,17 @@ struct bt_tags_iter_data {
|
|||
struct blk_mq_tags *tags;
|
||||
busy_tag_iter_fn *fn;
|
||||
void *data;
|
||||
bool reserved;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
#define BT_TAG_ITER_RESERVED (1 << 0)
|
||||
#define BT_TAG_ITER_STARTED (1 << 1)
|
||||
|
||||
static bool bt_tags_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
|
||||
{
|
||||
struct bt_tags_iter_data *iter_data = data;
|
||||
struct blk_mq_tags *tags = iter_data->tags;
|
||||
bool reserved = iter_data->reserved;
|
||||
bool reserved = iter_data->flags & BT_TAG_ITER_RESERVED;
|
||||
struct request *rq;
|
||||
|
||||
if (!reserved)
|
||||
|
@ -274,10 +277,12 @@ static bool bt_tags_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
|
|||
* test and set the bit before assining ->rqs[].
|
||||
*/
|
||||
rq = tags->rqs[bitnr];
|
||||
if (rq && blk_mq_request_started(rq))
|
||||
return iter_data->fn(rq, iter_data->data, reserved);
|
||||
|
||||
return true;
|
||||
if (!rq)
|
||||
return true;
|
||||
if ((iter_data->flags & BT_TAG_ITER_STARTED) &&
|
||||
!blk_mq_request_started(rq))
|
||||
return true;
|
||||
return iter_data->fn(rq, iter_data->data, reserved);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -290,39 +295,47 @@ static bool bt_tags_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
|
|||
* @reserved) where rq is a pointer to a request. Return true
|
||||
* to continue iterating tags, false to stop.
|
||||
* @data: Will be passed as second argument to @fn.
|
||||
* @reserved: Indicates whether @bt is the breserved_tags member or the
|
||||
* bitmap_tags member of struct blk_mq_tags.
|
||||
* @flags: BT_TAG_ITER_*
|
||||
*/
|
||||
static void bt_tags_for_each(struct blk_mq_tags *tags, struct sbitmap_queue *bt,
|
||||
busy_tag_iter_fn *fn, void *data, bool reserved)
|
||||
busy_tag_iter_fn *fn, void *data, unsigned int flags)
|
||||
{
|
||||
struct bt_tags_iter_data iter_data = {
|
||||
.tags = tags,
|
||||
.fn = fn,
|
||||
.data = data,
|
||||
.reserved = reserved,
|
||||
.flags = flags,
|
||||
};
|
||||
|
||||
if (tags->rqs)
|
||||
sbitmap_for_each_set(&bt->sb, bt_tags_iter, &iter_data);
|
||||
}
|
||||
|
||||
static void __blk_mq_all_tag_iter(struct blk_mq_tags *tags,
|
||||
busy_tag_iter_fn *fn, void *priv, unsigned int flags)
|
||||
{
|
||||
WARN_ON_ONCE(flags & BT_TAG_ITER_RESERVED);
|
||||
|
||||
if (tags->nr_reserved_tags)
|
||||
bt_tags_for_each(tags, &tags->breserved_tags, fn, priv,
|
||||
flags | BT_TAG_ITER_RESERVED);
|
||||
bt_tags_for_each(tags, &tags->bitmap_tags, fn, priv, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* blk_mq_all_tag_busy_iter - iterate over all started requests in a tag map
|
||||
* blk_mq_all_tag_iter - iterate over all requests in a tag map
|
||||
* @tags: Tag map to iterate over.
|
||||
* @fn: Pointer to the function that will be called for each started
|
||||
* @fn: Pointer to the function that will be called for each
|
||||
* request. @fn will be called as follows: @fn(rq, @priv,
|
||||
* reserved) where rq is a pointer to a request. 'reserved'
|
||||
* indicates whether or not @rq is a reserved request. Return
|
||||
* true to continue iterating tags, false to stop.
|
||||
* @priv: Will be passed as second argument to @fn.
|
||||
*/
|
||||
static void blk_mq_all_tag_busy_iter(struct blk_mq_tags *tags,
|
||||
busy_tag_iter_fn *fn, void *priv)
|
||||
void blk_mq_all_tag_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn,
|
||||
void *priv)
|
||||
{
|
||||
if (tags->nr_reserved_tags)
|
||||
bt_tags_for_each(tags, &tags->breserved_tags, fn, priv, true);
|
||||
bt_tags_for_each(tags, &tags->bitmap_tags, fn, priv, false);
|
||||
return __blk_mq_all_tag_iter(tags, fn, priv, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -342,7 +355,8 @@ void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset,
|
|||
|
||||
for (i = 0; i < tagset->nr_hw_queues; i++) {
|
||||
if (tagset->tags && tagset->tags[i])
|
||||
blk_mq_all_tag_busy_iter(tagset->tags[i], fn, priv);
|
||||
__blk_mq_all_tag_iter(tagset->tags[i], fn, priv,
|
||||
BT_TAG_ITER_STARTED);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(blk_mq_tagset_busy_iter);
|
||||
|
|
|
@ -34,6 +34,8 @@ extern int blk_mq_tag_update_depth(struct blk_mq_hw_ctx *hctx,
|
|||
extern void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags, bool);
|
||||
void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn,
|
||||
void *priv);
|
||||
void blk_mq_all_tag_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn,
|
||||
void *priv);
|
||||
|
||||
static inline struct sbq_wait_state *bt_wait_ptr(struct sbitmap_queue *bt,
|
||||
struct blk_mq_hw_ctx *hctx)
|
||||
|
|
Загрузка…
Ссылка в новой задаче