diff options
author | Omar Sandoval <osandov@fb.com> | 2017-05-04 03:31:34 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-05-04 10:25:17 -0400 |
commit | daaadb3e9453ab89c2e113a2d1df8e19e30944cc (patch) | |
tree | 4a72782bd1b32dd4b0757e993644ff98b7cbc9d5 | |
parent | 16b738f651c83a01db057e5db02ec4b830af9130 (diff) |
mq-deadline: add debugfs attributes
Expose the fifo lists, cached next requests, batching state, and
dispatch list. It'd also be possible to add the sorted lists, but there
aren't already seq_file helpers for rbtrees.
Signed-off-by: Omar Sandoval <osandov@fb.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | block/blk-mq-debugfs.c | 9 | ||||
-rw-r--r-- | block/blk-mq-debugfs.h | 1 | ||||
-rw-r--r-- | block/mq-deadline.c | 123 |
3 files changed, 131 insertions, 2 deletions
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c index 8ec738f872e5..803aed4d7221 100644 --- a/block/blk-mq-debugfs.c +++ b/block/blk-mq-debugfs.c | |||
@@ -267,9 +267,8 @@ static const char *const rqf_name[] = { | |||
267 | }; | 267 | }; |
268 | #undef RQF_NAME | 268 | #undef RQF_NAME |
269 | 269 | ||
270 | int blk_mq_debugfs_rq_show(struct seq_file *m, void *v) | 270 | int __blk_mq_debugfs_rq_show(struct seq_file *m, struct request *rq) |
271 | { | 271 | { |
272 | struct request *rq = list_entry_rq(v); | ||
273 | const struct blk_mq_ops *const mq_ops = rq->q->mq_ops; | 272 | const struct blk_mq_ops *const mq_ops = rq->q->mq_ops; |
274 | const unsigned int op = rq->cmd_flags & REQ_OP_MASK; | 273 | const unsigned int op = rq->cmd_flags & REQ_OP_MASK; |
275 | 274 | ||
@@ -291,6 +290,12 @@ int blk_mq_debugfs_rq_show(struct seq_file *m, void *v) | |||
291 | seq_puts(m, "}\n"); | 290 | seq_puts(m, "}\n"); |
292 | return 0; | 291 | return 0; |
293 | } | 292 | } |
293 | EXPORT_SYMBOL_GPL(__blk_mq_debugfs_rq_show); | ||
294 | |||
295 | int blk_mq_debugfs_rq_show(struct seq_file *m, void *v) | ||
296 | { | ||
297 | return __blk_mq_debugfs_rq_show(m, list_entry_rq(v)); | ||
298 | } | ||
294 | EXPORT_SYMBOL_GPL(blk_mq_debugfs_rq_show); | 299 | EXPORT_SYMBOL_GPL(blk_mq_debugfs_rq_show); |
295 | 300 | ||
296 | static void *hctx_dispatch_start(struct seq_file *m, loff_t *pos) | 301 | static void *hctx_dispatch_start(struct seq_file *m, loff_t *pos) |
diff --git a/block/blk-mq-debugfs.h b/block/blk-mq-debugfs.h index dd3bbfe74f46..a182e6f97565 100644 --- a/block/blk-mq-debugfs.h +++ b/block/blk-mq-debugfs.h | |||
@@ -14,6 +14,7 @@ struct blk_mq_debugfs_attr { | |||
14 | const struct seq_operations *seq_ops; | 14 | const struct seq_operations *seq_ops; |
15 | }; | 15 | }; |
16 | 16 | ||
17 | int __blk_mq_debugfs_rq_show(struct seq_file *m, struct request *rq); | ||
17 | int blk_mq_debugfs_rq_show(struct seq_file *m, void *v); | 18 | int blk_mq_debugfs_rq_show(struct seq_file *m, void *v); |
18 | 19 | ||
19 | int blk_mq_debugfs_register(struct request_queue *q); | 20 | int blk_mq_debugfs_register(struct request_queue *q); |
diff --git a/block/mq-deadline.c b/block/mq-deadline.c index 236121633ca0..1b964a387afe 100644 --- a/block/mq-deadline.c +++ b/block/mq-deadline.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include "blk.h" | 20 | #include "blk.h" |
21 | #include "blk-mq.h" | 21 | #include "blk-mq.h" |
22 | #include "blk-mq-debugfs.h" | ||
22 | #include "blk-mq-tag.h" | 23 | #include "blk-mq-tag.h" |
23 | #include "blk-mq-sched.h" | 24 | #include "blk-mq-sched.h" |
24 | 25 | ||
@@ -517,6 +518,125 @@ static struct elv_fs_entry deadline_attrs[] = { | |||
517 | __ATTR_NULL | 518 | __ATTR_NULL |
518 | }; | 519 | }; |
519 | 520 | ||
521 | #ifdef CONFIG_BLK_DEBUG_FS | ||
522 | #define DEADLINE_DEBUGFS_DDIR_ATTRS(ddir, name) \ | ||
523 | static void *deadline_##name##_fifo_start(struct seq_file *m, \ | ||
524 | loff_t *pos) \ | ||
525 | __acquires(&dd->lock) \ | ||
526 | { \ | ||
527 | struct request_queue *q = m->private; \ | ||
528 | struct deadline_data *dd = q->elevator->elevator_data; \ | ||
529 | \ | ||
530 | spin_lock(&dd->lock); \ | ||
531 | return seq_list_start(&dd->fifo_list[ddir], *pos); \ | ||
532 | } \ | ||
533 | \ | ||
534 | static void *deadline_##name##_fifo_next(struct seq_file *m, void *v, \ | ||
535 | loff_t *pos) \ | ||
536 | { \ | ||
537 | struct request_queue *q = m->private; \ | ||
538 | struct deadline_data *dd = q->elevator->elevator_data; \ | ||
539 | \ | ||
540 | return seq_list_next(v, &dd->fifo_list[ddir], pos); \ | ||
541 | } \ | ||
542 | \ | ||
543 | static void deadline_##name##_fifo_stop(struct seq_file *m, void *v) \ | ||
544 | __releases(&dd->lock) \ | ||
545 | { \ | ||
546 | struct request_queue *q = m->private; \ | ||
547 | struct deadline_data *dd = q->elevator->elevator_data; \ | ||
548 | \ | ||
549 | spin_unlock(&dd->lock); \ | ||
550 | } \ | ||
551 | \ | ||
552 | static const struct seq_operations deadline_##name##_fifo_seq_ops = { \ | ||
553 | .start = deadline_##name##_fifo_start, \ | ||
554 | .next = deadline_##name##_fifo_next, \ | ||
555 | .stop = deadline_##name##_fifo_stop, \ | ||
556 | .show = blk_mq_debugfs_rq_show, \ | ||
557 | }; \ | ||
558 | \ | ||
559 | static int deadline_##name##_next_rq_show(void *data, \ | ||
560 | struct seq_file *m) \ | ||
561 | { \ | ||
562 | struct request_queue *q = data; \ | ||
563 | struct deadline_data *dd = q->elevator->elevator_data; \ | ||
564 | struct request *rq = dd->next_rq[ddir]; \ | ||
565 | \ | ||
566 | if (rq) \ | ||
567 | __blk_mq_debugfs_rq_show(m, rq); \ | ||
568 | return 0; \ | ||
569 | } | ||
570 | DEADLINE_DEBUGFS_DDIR_ATTRS(READ, read) | ||
571 | DEADLINE_DEBUGFS_DDIR_ATTRS(WRITE, write) | ||
572 | #undef DEADLINE_DEBUGFS_DDIR_ATTRS | ||
573 | |||
574 | static int deadline_batching_show(void *data, struct seq_file *m) | ||
575 | { | ||
576 | struct request_queue *q = data; | ||
577 | struct deadline_data *dd = q->elevator->elevator_data; | ||
578 | |||
579 | seq_printf(m, "%u\n", dd->batching); | ||
580 | return 0; | ||
581 | } | ||
582 | |||
583 | static int deadline_starved_show(void *data, struct seq_file *m) | ||
584 | { | ||
585 | struct request_queue *q = data; | ||
586 | struct deadline_data *dd = q->elevator->elevator_data; | ||
587 | |||
588 | seq_printf(m, "%u\n", dd->starved); | ||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | static void *deadline_dispatch_start(struct seq_file *m, loff_t *pos) | ||
593 | __acquires(&dd->lock) | ||
594 | { | ||
595 | struct request_queue *q = m->private; | ||
596 | struct deadline_data *dd = q->elevator->elevator_data; | ||
597 | |||
598 | spin_lock(&dd->lock); | ||
599 | return seq_list_start(&dd->dispatch, *pos); | ||
600 | } | ||
601 | |||
602 | static void *deadline_dispatch_next(struct seq_file *m, void *v, loff_t *pos) | ||
603 | { | ||
604 | struct request_queue *q = m->private; | ||
605 | struct deadline_data *dd = q->elevator->elevator_data; | ||
606 | |||
607 | return seq_list_next(v, &dd->dispatch, pos); | ||
608 | } | ||
609 | |||
610 | static void deadline_dispatch_stop(struct seq_file *m, void *v) | ||
611 | __releases(&dd->lock) | ||
612 | { | ||
613 | struct request_queue *q = m->private; | ||
614 | struct deadline_data *dd = q->elevator->elevator_data; | ||
615 | |||
616 | spin_unlock(&dd->lock); | ||
617 | } | ||
618 | |||
619 | static const struct seq_operations deadline_dispatch_seq_ops = { | ||
620 | .start = deadline_dispatch_start, | ||
621 | .next = deadline_dispatch_next, | ||
622 | .stop = deadline_dispatch_stop, | ||
623 | .show = blk_mq_debugfs_rq_show, | ||
624 | }; | ||
625 | |||
626 | #define DEADLINE_QUEUE_DDIR_ATTRS(name) \ | ||
627 | {#name "_fifo_list", 0400, .seq_ops = &deadline_##name##_fifo_seq_ops}, \ | ||
628 | {#name "_next_rq", 0400, deadline_##name##_next_rq_show} | ||
629 | static const struct blk_mq_debugfs_attr deadline_queue_debugfs_attrs[] = { | ||
630 | DEADLINE_QUEUE_DDIR_ATTRS(read), | ||
631 | DEADLINE_QUEUE_DDIR_ATTRS(write), | ||
632 | {"batching", 0400, deadline_batching_show}, | ||
633 | {"starved", 0400, deadline_starved_show}, | ||
634 | {"dispatch", 0400, .seq_ops = &deadline_dispatch_seq_ops}, | ||
635 | {}, | ||
636 | }; | ||
637 | #undef DEADLINE_QUEUE_DDIR_ATTRS | ||
638 | #endif | ||
639 | |||
520 | static struct elevator_type mq_deadline = { | 640 | static struct elevator_type mq_deadline = { |
521 | .ops.mq = { | 641 | .ops.mq = { |
522 | .insert_requests = dd_insert_requests, | 642 | .insert_requests = dd_insert_requests, |
@@ -533,6 +653,9 @@ static struct elevator_type mq_deadline = { | |||
533 | }, | 653 | }, |
534 | 654 | ||
535 | .uses_mq = true, | 655 | .uses_mq = true, |
656 | #ifdef CONFIG_BLK_DEBUG_FS | ||
657 | .queue_debugfs_attrs = deadline_queue_debugfs_attrs, | ||
658 | #endif | ||
536 | .elevator_attrs = deadline_attrs, | 659 | .elevator_attrs = deadline_attrs, |
537 | .elevator_name = "mq-deadline", | 660 | .elevator_name = "mq-deadline", |
538 | .elevator_owner = THIS_MODULE, | 661 | .elevator_owner = THIS_MODULE, |