diff options
Diffstat (limited to 'block/kyber-iosched.c')
-rw-r--r-- | block/kyber-iosched.c | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/block/kyber-iosched.c b/block/kyber-iosched.c index adc8e6393829..2b62e362fb36 100644 --- a/block/kyber-iosched.c +++ b/block/kyber-iosched.c | |||
@@ -30,6 +30,9 @@ | |||
30 | #include "blk-mq-sched.h" | 30 | #include "blk-mq-sched.h" |
31 | #include "blk-mq-tag.h" | 31 | #include "blk-mq-tag.h" |
32 | 32 | ||
33 | #define CREATE_TRACE_POINTS | ||
34 | #include <trace/events/kyber.h> | ||
35 | |||
33 | /* | 36 | /* |
34 | * Scheduling domains: the device is divided into multiple domains based on the | 37 | * Scheduling domains: the device is divided into multiple domains based on the |
35 | * request type. | 38 | * request type. |
@@ -42,6 +45,13 @@ enum { | |||
42 | KYBER_NUM_DOMAINS, | 45 | KYBER_NUM_DOMAINS, |
43 | }; | 46 | }; |
44 | 47 | ||
48 | static const char *kyber_domain_names[] = { | ||
49 | [KYBER_READ] = "READ", | ||
50 | [KYBER_WRITE] = "WRITE", | ||
51 | [KYBER_DISCARD] = "DISCARD", | ||
52 | [KYBER_OTHER] = "OTHER", | ||
53 | }; | ||
54 | |||
45 | enum { | 55 | enum { |
46 | /* | 56 | /* |
47 | * In order to prevent starvation of synchronous requests by a flood of | 57 | * In order to prevent starvation of synchronous requests by a flood of |
@@ -122,6 +132,11 @@ enum { | |||
122 | KYBER_IO_LATENCY, | 132 | KYBER_IO_LATENCY, |
123 | }; | 133 | }; |
124 | 134 | ||
135 | static const char *kyber_latency_type_names[] = { | ||
136 | [KYBER_TOTAL_LATENCY] = "total", | ||
137 | [KYBER_IO_LATENCY] = "I/O", | ||
138 | }; | ||
139 | |||
125 | /* | 140 | /* |
126 | * Per-cpu latency histograms: total latency and I/O latency for each scheduling | 141 | * Per-cpu latency histograms: total latency and I/O latency for each scheduling |
127 | * domain except for KYBER_OTHER. | 142 | * domain except for KYBER_OTHER. |
@@ -144,6 +159,8 @@ struct kyber_ctx_queue { | |||
144 | } ____cacheline_aligned_in_smp; | 159 | } ____cacheline_aligned_in_smp; |
145 | 160 | ||
146 | struct kyber_queue_data { | 161 | struct kyber_queue_data { |
162 | struct request_queue *q; | ||
163 | |||
147 | /* | 164 | /* |
148 | * Each scheduling domain has a limited number of in-flight requests | 165 | * Each scheduling domain has a limited number of in-flight requests |
149 | * device-wide, limited by these tokens. | 166 | * device-wide, limited by these tokens. |
@@ -249,6 +266,10 @@ static int calculate_percentile(struct kyber_queue_data *kqd, | |||
249 | } | 266 | } |
250 | memset(buckets, 0, sizeof(kqd->latency_buckets[sched_domain][type])); | 267 | memset(buckets, 0, sizeof(kqd->latency_buckets[sched_domain][type])); |
251 | 268 | ||
269 | trace_kyber_latency(kqd->q, kyber_domain_names[sched_domain], | ||
270 | kyber_latency_type_names[type], percentile, | ||
271 | bucket + 1, 1 << KYBER_LATENCY_SHIFT, samples); | ||
272 | |||
252 | return bucket; | 273 | return bucket; |
253 | } | 274 | } |
254 | 275 | ||
@@ -256,8 +277,11 @@ static void kyber_resize_domain(struct kyber_queue_data *kqd, | |||
256 | unsigned int sched_domain, unsigned int depth) | 277 | unsigned int sched_domain, unsigned int depth) |
257 | { | 278 | { |
258 | depth = clamp(depth, 1U, kyber_depth[sched_domain]); | 279 | depth = clamp(depth, 1U, kyber_depth[sched_domain]); |
259 | if (depth != kqd->domain_tokens[sched_domain].sb.depth) | 280 | if (depth != kqd->domain_tokens[sched_domain].sb.depth) { |
260 | sbitmap_queue_resize(&kqd->domain_tokens[sched_domain], depth); | 281 | sbitmap_queue_resize(&kqd->domain_tokens[sched_domain], depth); |
282 | trace_kyber_adjust(kqd->q, kyber_domain_names[sched_domain], | ||
283 | depth); | ||
284 | } | ||
261 | } | 285 | } |
262 | 286 | ||
263 | static void kyber_timer_fn(struct timer_list *t) | 287 | static void kyber_timer_fn(struct timer_list *t) |
@@ -360,6 +384,8 @@ static struct kyber_queue_data *kyber_queue_data_alloc(struct request_queue *q) | |||
360 | if (!kqd) | 384 | if (!kqd) |
361 | goto err; | 385 | goto err; |
362 | 386 | ||
387 | kqd->q = q; | ||
388 | |||
363 | kqd->cpu_latency = alloc_percpu_gfp(struct kyber_cpu_latency, | 389 | kqd->cpu_latency = alloc_percpu_gfp(struct kyber_cpu_latency, |
364 | GFP_KERNEL | __GFP_ZERO); | 390 | GFP_KERNEL | __GFP_ZERO); |
365 | if (!kqd->cpu_latency) | 391 | if (!kqd->cpu_latency) |
@@ -756,6 +782,9 @@ kyber_dispatch_cur_domain(struct kyber_queue_data *kqd, | |||
756 | rq_set_domain_token(rq, nr); | 782 | rq_set_domain_token(rq, nr); |
757 | list_del_init(&rq->queuelist); | 783 | list_del_init(&rq->queuelist); |
758 | return rq; | 784 | return rq; |
785 | } else { | ||
786 | trace_kyber_throttled(kqd->q, | ||
787 | kyber_domain_names[khd->cur_domain]); | ||
759 | } | 788 | } |
760 | } else if (sbitmap_any_bit_set(&khd->kcq_map[khd->cur_domain])) { | 789 | } else if (sbitmap_any_bit_set(&khd->kcq_map[khd->cur_domain])) { |
761 | nr = kyber_get_domain_token(kqd, khd, hctx); | 790 | nr = kyber_get_domain_token(kqd, khd, hctx); |
@@ -766,6 +795,9 @@ kyber_dispatch_cur_domain(struct kyber_queue_data *kqd, | |||
766 | rq_set_domain_token(rq, nr); | 795 | rq_set_domain_token(rq, nr); |
767 | list_del_init(&rq->queuelist); | 796 | list_del_init(&rq->queuelist); |
768 | return rq; | 797 | return rq; |
798 | } else { | ||
799 | trace_kyber_throttled(kqd->q, | ||
800 | kyber_domain_names[khd->cur_domain]); | ||
769 | } | 801 | } |
770 | } | 802 | } |
771 | 803 | ||
@@ -944,23 +976,7 @@ static int kyber_cur_domain_show(void *data, struct seq_file *m) | |||
944 | struct blk_mq_hw_ctx *hctx = data; | 976 | struct blk_mq_hw_ctx *hctx = data; |
945 | struct kyber_hctx_data *khd = hctx->sched_data; | 977 | struct kyber_hctx_data *khd = hctx->sched_data; |
946 | 978 | ||
947 | switch (khd->cur_domain) { | 979 | seq_printf(m, "%s\n", kyber_domain_names[khd->cur_domain]); |
948 | case KYBER_READ: | ||
949 | seq_puts(m, "READ\n"); | ||
950 | break; | ||
951 | case KYBER_WRITE: | ||
952 | seq_puts(m, "WRITE\n"); | ||
953 | break; | ||
954 | case KYBER_DISCARD: | ||
955 | seq_puts(m, "DISCARD\n"); | ||
956 | break; | ||
957 | case KYBER_OTHER: | ||
958 | seq_puts(m, "OTHER\n"); | ||
959 | break; | ||
960 | default: | ||
961 | seq_printf(m, "%u\n", khd->cur_domain); | ||
962 | break; | ||
963 | } | ||
964 | return 0; | 980 | return 0; |
965 | } | 981 | } |
966 | 982 | ||