diff options
author | Bart Van Assche <bart.vanassche@sandisk.com> | 2017-06-01 11:55:12 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-06-01 15:02:59 -0400 |
commit | 2720bab50258782573df0f536681bece11e784f0 (patch) | |
tree | 06a2527f7094bc2da1e4fbb681db28743d6fa804 /block/blk-mq-debugfs.c | |
parent | 8ef1a191038c138d5675933cd69d47747d0d396b (diff) |
blk-mq-debugfs: Show busy requests
Requests that got stuck in a block driver are neither on
blk_mq_ctx.rq_list nor on any hw dispatch queue. Make these
visible in debugfs through the "busy" attribute.
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Eduardo Valentin <eduval@amazon.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block/blk-mq-debugfs.c')
-rw-r--r-- | block/blk-mq-debugfs.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c index 8b06a12c1461..90c454bbaf92 100644 --- a/block/blk-mq-debugfs.c +++ b/block/blk-mq-debugfs.c | |||
@@ -370,6 +370,36 @@ static const struct seq_operations hctx_dispatch_seq_ops = { | |||
370 | .show = blk_mq_debugfs_rq_show, | 370 | .show = blk_mq_debugfs_rq_show, |
371 | }; | 371 | }; |
372 | 372 | ||
373 | struct show_busy_params { | ||
374 | struct seq_file *m; | ||
375 | struct blk_mq_hw_ctx *hctx; | ||
376 | }; | ||
377 | |||
378 | /* | ||
379 | * Note: the state of a request may change while this function is in progress, | ||
380 | * e.g. due to a concurrent blk_mq_finish_request() call. | ||
381 | */ | ||
382 | static void hctx_show_busy_rq(struct request *rq, void *data, bool reserved) | ||
383 | { | ||
384 | const struct show_busy_params *params = data; | ||
385 | |||
386 | if (blk_mq_map_queue(rq->q, rq->mq_ctx->cpu) == params->hctx && | ||
387 | test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) | ||
388 | __blk_mq_debugfs_rq_show(params->m, | ||
389 | list_entry_rq(&rq->queuelist)); | ||
390 | } | ||
391 | |||
392 | static int hctx_busy_show(void *data, struct seq_file *m) | ||
393 | { | ||
394 | struct blk_mq_hw_ctx *hctx = data; | ||
395 | struct show_busy_params params = { .m = m, .hctx = hctx }; | ||
396 | |||
397 | blk_mq_tagset_busy_iter(hctx->queue->tag_set, hctx_show_busy_rq, | ||
398 | ¶ms); | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | |||
373 | static int hctx_ctx_map_show(void *data, struct seq_file *m) | 403 | static int hctx_ctx_map_show(void *data, struct seq_file *m) |
374 | { | 404 | { |
375 | struct blk_mq_hw_ctx *hctx = data; | 405 | struct blk_mq_hw_ctx *hctx = data; |
@@ -705,6 +735,7 @@ static const struct blk_mq_debugfs_attr blk_mq_debugfs_hctx_attrs[] = { | |||
705 | {"state", 0400, hctx_state_show}, | 735 | {"state", 0400, hctx_state_show}, |
706 | {"flags", 0400, hctx_flags_show}, | 736 | {"flags", 0400, hctx_flags_show}, |
707 | {"dispatch", 0400, .seq_ops = &hctx_dispatch_seq_ops}, | 737 | {"dispatch", 0400, .seq_ops = &hctx_dispatch_seq_ops}, |
738 | {"busy", 0400, hctx_busy_show}, | ||
708 | {"ctx_map", 0400, hctx_ctx_map_show}, | 739 | {"ctx_map", 0400, hctx_ctx_map_show}, |
709 | {"tags", 0400, hctx_tags_show}, | 740 | {"tags", 0400, hctx_tags_show}, |
710 | {"tags_bitmap", 0400, hctx_tags_bitmap_show}, | 741 | {"tags_bitmap", 0400, hctx_tags_bitmap_show}, |