diff options
author | Omar Sandoval <osandov@fb.com> | 2017-05-04 03:31:33 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-05-04 10:25:17 -0400 |
commit | 16b738f651c83a01db057e5db02ec4b830af9130 (patch) | |
tree | b2d8d7399a0ec9dc103494ec67926d24ec4b54eb | |
parent | d332ce091813d11a46144354baa72b755833392f (diff) |
kyber: add debugfs attributes
Expose the domain token pools, asynchronous sbitmap depth, domain
request lists, and batching state.
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 | 3 | ||||
-rw-r--r-- | block/blk-mq-debugfs.h | 2 | ||||
-rw-r--r-- | block/kyber-iosched.c | 130 |
3 files changed, 134 insertions, 1 deletions
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c index a3b887109310..8ec738f872e5 100644 --- a/block/blk-mq-debugfs.c +++ b/block/blk-mq-debugfs.c | |||
@@ -267,7 +267,7 @@ static const char *const rqf_name[] = { | |||
267 | }; | 267 | }; |
268 | #undef RQF_NAME | 268 | #undef RQF_NAME |
269 | 269 | ||
270 | static int blk_mq_debugfs_rq_show(struct seq_file *m, void *v) | 270 | int blk_mq_debugfs_rq_show(struct seq_file *m, void *v) |
271 | { | 271 | { |
272 | struct request *rq = list_entry_rq(v); | 272 | struct request *rq = list_entry_rq(v); |
273 | const struct blk_mq_ops *const mq_ops = rq->q->mq_ops; | 273 | const struct blk_mq_ops *const mq_ops = rq->q->mq_ops; |
@@ -291,6 +291,7 @@ static int blk_mq_debugfs_rq_show(struct seq_file *m, void *v) | |||
291 | seq_puts(m, "}\n"); | 291 | seq_puts(m, "}\n"); |
292 | return 0; | 292 | return 0; |
293 | } | 293 | } |
294 | EXPORT_SYMBOL_GPL(blk_mq_debugfs_rq_show); | ||
294 | 295 | ||
295 | static void *hctx_dispatch_start(struct seq_file *m, loff_t *pos) | 296 | static void *hctx_dispatch_start(struct seq_file *m, loff_t *pos) |
296 | __acquires(&hctx->lock) | 297 | __acquires(&hctx->lock) |
diff --git a/block/blk-mq-debugfs.h b/block/blk-mq-debugfs.h index a5ac21c81ea3..dd3bbfe74f46 100644 --- a/block/blk-mq-debugfs.h +++ b/block/blk-mq-debugfs.h | |||
@@ -14,6 +14,8 @@ 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, void *v); | ||
18 | |||
17 | int blk_mq_debugfs_register(struct request_queue *q); | 19 | int blk_mq_debugfs_register(struct request_queue *q); |
18 | void blk_mq_debugfs_unregister(struct request_queue *q); | 20 | void blk_mq_debugfs_unregister(struct request_queue *q); |
19 | int blk_mq_debugfs_register_hctx(struct request_queue *q, | 21 | int blk_mq_debugfs_register_hctx(struct request_queue *q, |
diff --git a/block/kyber-iosched.c b/block/kyber-iosched.c index 3b0090bc5dd1..b9faabc75fdb 100644 --- a/block/kyber-iosched.c +++ b/block/kyber-iosched.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #include "blk.h" | 27 | #include "blk.h" |
28 | #include "blk-mq.h" | 28 | #include "blk-mq.h" |
29 | #include "blk-mq-debugfs.h" | ||
29 | #include "blk-mq-sched.h" | 30 | #include "blk-mq-sched.h" |
30 | #include "blk-mq-tag.h" | 31 | #include "blk-mq-tag.h" |
31 | #include "blk-stat.h" | 32 | #include "blk-stat.h" |
@@ -683,6 +684,131 @@ static struct elv_fs_entry kyber_sched_attrs[] = { | |||
683 | }; | 684 | }; |
684 | #undef KYBER_LAT_ATTR | 685 | #undef KYBER_LAT_ATTR |
685 | 686 | ||
687 | #ifdef CONFIG_BLK_DEBUG_FS | ||
688 | #define KYBER_DEBUGFS_DOMAIN_ATTRS(domain, name) \ | ||
689 | static int kyber_##name##_tokens_show(void *data, struct seq_file *m) \ | ||
690 | { \ | ||
691 | struct request_queue *q = data; \ | ||
692 | struct kyber_queue_data *kqd = q->elevator->elevator_data; \ | ||
693 | \ | ||
694 | sbitmap_queue_show(&kqd->domain_tokens[domain], m); \ | ||
695 | return 0; \ | ||
696 | } \ | ||
697 | \ | ||
698 | static void *kyber_##name##_rqs_start(struct seq_file *m, loff_t *pos) \ | ||
699 | __acquires(&khd->lock) \ | ||
700 | { \ | ||
701 | struct blk_mq_hw_ctx *hctx = m->private; \ | ||
702 | struct kyber_hctx_data *khd = hctx->sched_data; \ | ||
703 | \ | ||
704 | spin_lock(&khd->lock); \ | ||
705 | return seq_list_start(&khd->rqs[domain], *pos); \ | ||
706 | } \ | ||
707 | \ | ||
708 | static void *kyber_##name##_rqs_next(struct seq_file *m, void *v, \ | ||
709 | loff_t *pos) \ | ||
710 | { \ | ||
711 | struct blk_mq_hw_ctx *hctx = m->private; \ | ||
712 | struct kyber_hctx_data *khd = hctx->sched_data; \ | ||
713 | \ | ||
714 | return seq_list_next(v, &khd->rqs[domain], pos); \ | ||
715 | } \ | ||
716 | \ | ||
717 | static void kyber_##name##_rqs_stop(struct seq_file *m, void *v) \ | ||
718 | __releases(&khd->lock) \ | ||
719 | { \ | ||
720 | struct blk_mq_hw_ctx *hctx = m->private; \ | ||
721 | struct kyber_hctx_data *khd = hctx->sched_data; \ | ||
722 | \ | ||
723 | spin_unlock(&khd->lock); \ | ||
724 | } \ | ||
725 | \ | ||
726 | static const struct seq_operations kyber_##name##_rqs_seq_ops = { \ | ||
727 | .start = kyber_##name##_rqs_start, \ | ||
728 | .next = kyber_##name##_rqs_next, \ | ||
729 | .stop = kyber_##name##_rqs_stop, \ | ||
730 | .show = blk_mq_debugfs_rq_show, \ | ||
731 | }; \ | ||
732 | \ | ||
733 | static int kyber_##name##_waiting_show(void *data, struct seq_file *m) \ | ||
734 | { \ | ||
735 | struct blk_mq_hw_ctx *hctx = data; \ | ||
736 | struct kyber_hctx_data *khd = hctx->sched_data; \ | ||
737 | wait_queue_t *wait = &khd->domain_wait[domain]; \ | ||
738 | \ | ||
739 | seq_printf(m, "%d\n", !list_empty_careful(&wait->task_list)); \ | ||
740 | return 0; \ | ||
741 | } | ||
742 | KYBER_DEBUGFS_DOMAIN_ATTRS(KYBER_READ, read) | ||
743 | KYBER_DEBUGFS_DOMAIN_ATTRS(KYBER_SYNC_WRITE, sync_write) | ||
744 | KYBER_DEBUGFS_DOMAIN_ATTRS(KYBER_OTHER, other) | ||
745 | #undef KYBER_DEBUGFS_DOMAIN_ATTRS | ||
746 | |||
747 | static int kyber_async_depth_show(void *data, struct seq_file *m) | ||
748 | { | ||
749 | struct request_queue *q = data; | ||
750 | struct kyber_queue_data *kqd = q->elevator->elevator_data; | ||
751 | |||
752 | seq_printf(m, "%u\n", kqd->async_depth); | ||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | static int kyber_cur_domain_show(void *data, struct seq_file *m) | ||
757 | { | ||
758 | struct blk_mq_hw_ctx *hctx = data; | ||
759 | struct kyber_hctx_data *khd = hctx->sched_data; | ||
760 | |||
761 | switch (khd->cur_domain) { | ||
762 | case KYBER_READ: | ||
763 | seq_puts(m, "READ\n"); | ||
764 | break; | ||
765 | case KYBER_SYNC_WRITE: | ||
766 | seq_puts(m, "SYNC_WRITE\n"); | ||
767 | break; | ||
768 | case KYBER_OTHER: | ||
769 | seq_puts(m, "OTHER\n"); | ||
770 | break; | ||
771 | default: | ||
772 | seq_printf(m, "%u\n", khd->cur_domain); | ||
773 | break; | ||
774 | } | ||
775 | return 0; | ||
776 | } | ||
777 | |||
778 | static int kyber_batching_show(void *data, struct seq_file *m) | ||
779 | { | ||
780 | struct blk_mq_hw_ctx *hctx = data; | ||
781 | struct kyber_hctx_data *khd = hctx->sched_data; | ||
782 | |||
783 | seq_printf(m, "%u\n", khd->batching); | ||
784 | return 0; | ||
785 | } | ||
786 | |||
787 | #define KYBER_QUEUE_DOMAIN_ATTRS(name) \ | ||
788 | {#name "_tokens", 0400, kyber_##name##_tokens_show} | ||
789 | static const struct blk_mq_debugfs_attr kyber_queue_debugfs_attrs[] = { | ||
790 | KYBER_QUEUE_DOMAIN_ATTRS(read), | ||
791 | KYBER_QUEUE_DOMAIN_ATTRS(sync_write), | ||
792 | KYBER_QUEUE_DOMAIN_ATTRS(other), | ||
793 | {"async_depth", 0400, kyber_async_depth_show}, | ||
794 | {}, | ||
795 | }; | ||
796 | #undef KYBER_QUEUE_DOMAIN_ATTRS | ||
797 | |||
798 | #define KYBER_HCTX_DOMAIN_ATTRS(name) \ | ||
799 | {#name "_rqs", 0400, .seq_ops = &kyber_##name##_rqs_seq_ops}, \ | ||
800 | {#name "_waiting", 0400, kyber_##name##_waiting_show} | ||
801 | static const struct blk_mq_debugfs_attr kyber_hctx_debugfs_attrs[] = { | ||
802 | KYBER_HCTX_DOMAIN_ATTRS(read), | ||
803 | KYBER_HCTX_DOMAIN_ATTRS(sync_write), | ||
804 | KYBER_HCTX_DOMAIN_ATTRS(other), | ||
805 | {"cur_domain", 0400, kyber_cur_domain_show}, | ||
806 | {"batching", 0400, kyber_batching_show}, | ||
807 | {}, | ||
808 | }; | ||
809 | #undef KYBER_HCTX_DOMAIN_ATTRS | ||
810 | #endif | ||
811 | |||
686 | static struct elevator_type kyber_sched = { | 812 | static struct elevator_type kyber_sched = { |
687 | .ops.mq = { | 813 | .ops.mq = { |
688 | .init_sched = kyber_init_sched, | 814 | .init_sched = kyber_init_sched, |
@@ -696,6 +822,10 @@ static struct elevator_type kyber_sched = { | |||
696 | .has_work = kyber_has_work, | 822 | .has_work = kyber_has_work, |
697 | }, | 823 | }, |
698 | .uses_mq = true, | 824 | .uses_mq = true, |
825 | #ifdef CONFIG_BLK_DEBUG_FS | ||
826 | .queue_debugfs_attrs = kyber_queue_debugfs_attrs, | ||
827 | .hctx_debugfs_attrs = kyber_hctx_debugfs_attrs, | ||
828 | #endif | ||
699 | .elevator_attrs = kyber_sched_attrs, | 829 | .elevator_attrs = kyber_sched_attrs, |
700 | .elevator_name = "kyber", | 830 | .elevator_name = "kyber", |
701 | .elevator_owner = THIS_MODULE, | 831 | .elevator_owner = THIS_MODULE, |