summaryrefslogtreecommitdiffstats
path: root/block/kyber-iosched.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/kyber-iosched.c')
-rw-r--r--block/kyber-iosched.c52
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
48static const char *kyber_domain_names[] = {
49 [KYBER_READ] = "READ",
50 [KYBER_WRITE] = "WRITE",
51 [KYBER_DISCARD] = "DISCARD",
52 [KYBER_OTHER] = "OTHER",
53};
54
45enum { 55enum {
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
135static 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
146struct kyber_queue_data { 161struct 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
263static void kyber_timer_fn(struct timer_list *t) 287static 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