Skip to content

Commit

Permalink
kyber: avoid q->disk dereferences in trace points
Browse files Browse the repository at this point in the history
q->disk becomes invalid after the gendisk is removed.  Work around this
by caching the dev_t for the tracepoints.  The real fix would be to
properly tear down the I/O schedulers with the gendisk, but that is
a much more invasive change.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20211012093301.GA27795@lst.de
Tested-by: Yi Zhang <yi.zhang@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Christoph Hellwig authored and axboe committed Oct 16, 2021
1 parent aec89dc commit c411080
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 14 deletions.
10 changes: 6 additions & 4 deletions block/kyber-iosched.c
Expand Up @@ -151,6 +151,7 @@ struct kyber_ctx_queue {

struct kyber_queue_data {
struct request_queue *q;
dev_t dev;

/*
* Each scheduling domain has a limited number of in-flight requests
Expand Down Expand Up @@ -257,7 +258,7 @@ static int calculate_percentile(struct kyber_queue_data *kqd,
}
memset(buckets, 0, sizeof(kqd->latency_buckets[sched_domain][type]));

trace_kyber_latency(kqd->q, kyber_domain_names[sched_domain],
trace_kyber_latency(kqd->dev, kyber_domain_names[sched_domain],
kyber_latency_type_names[type], percentile,
bucket + 1, 1 << KYBER_LATENCY_SHIFT, samples);

Expand All @@ -270,7 +271,7 @@ static void kyber_resize_domain(struct kyber_queue_data *kqd,
depth = clamp(depth, 1U, kyber_depth[sched_domain]);
if (depth != kqd->domain_tokens[sched_domain].sb.depth) {
sbitmap_queue_resize(&kqd->domain_tokens[sched_domain], depth);
trace_kyber_adjust(kqd->q, kyber_domain_names[sched_domain],
trace_kyber_adjust(kqd->dev, kyber_domain_names[sched_domain],
depth);
}
}
Expand Down Expand Up @@ -366,6 +367,7 @@ static struct kyber_queue_data *kyber_queue_data_alloc(struct request_queue *q)
goto err;

kqd->q = q;
kqd->dev = disk_devt(q->disk);

kqd->cpu_latency = alloc_percpu_gfp(struct kyber_cpu_latency,
GFP_KERNEL | __GFP_ZERO);
Expand Down Expand Up @@ -774,7 +776,7 @@ kyber_dispatch_cur_domain(struct kyber_queue_data *kqd,
list_del_init(&rq->queuelist);
return rq;
} else {
trace_kyber_throttled(kqd->q,
trace_kyber_throttled(kqd->dev,
kyber_domain_names[khd->cur_domain]);
}
} else if (sbitmap_any_bit_set(&khd->kcq_map[khd->cur_domain])) {
Expand All @@ -787,7 +789,7 @@ kyber_dispatch_cur_domain(struct kyber_queue_data *kqd,
list_del_init(&rq->queuelist);
return rq;
} else {
trace_kyber_throttled(kqd->q,
trace_kyber_throttled(kqd->dev,
kyber_domain_names[khd->cur_domain]);
}
}
Expand Down
19 changes: 9 additions & 10 deletions include/trace/events/kyber.h
Expand Up @@ -13,11 +13,11 @@

TRACE_EVENT(kyber_latency,

TP_PROTO(struct request_queue *q, const char *domain, const char *type,
TP_PROTO(dev_t dev, const char *domain, const char *type,
unsigned int percentile, unsigned int numerator,
unsigned int denominator, unsigned int samples),

TP_ARGS(q, domain, type, percentile, numerator, denominator, samples),
TP_ARGS(dev, domain, type, percentile, numerator, denominator, samples),

TP_STRUCT__entry(
__field( dev_t, dev )
Expand All @@ -30,7 +30,7 @@ TRACE_EVENT(kyber_latency,
),

TP_fast_assign(
__entry->dev = disk_devt(q->disk);
__entry->dev = dev;
strlcpy(__entry->domain, domain, sizeof(__entry->domain));
strlcpy(__entry->type, type, sizeof(__entry->type));
__entry->percentile = percentile;
Expand All @@ -47,10 +47,9 @@ TRACE_EVENT(kyber_latency,

TRACE_EVENT(kyber_adjust,

TP_PROTO(struct request_queue *q, const char *domain,
unsigned int depth),
TP_PROTO(dev_t dev, const char *domain, unsigned int depth),

TP_ARGS(q, domain, depth),
TP_ARGS(dev, domain, depth),

TP_STRUCT__entry(
__field( dev_t, dev )
Expand All @@ -59,7 +58,7 @@ TRACE_EVENT(kyber_adjust,
),

TP_fast_assign(
__entry->dev = disk_devt(q->disk);
__entry->dev = dev;
strlcpy(__entry->domain, domain, sizeof(__entry->domain));
__entry->depth = depth;
),
Expand All @@ -71,17 +70,17 @@ TRACE_EVENT(kyber_adjust,

TRACE_EVENT(kyber_throttled,

TP_PROTO(struct request_queue *q, const char *domain),
TP_PROTO(dev_t dev, const char *domain),

TP_ARGS(q, domain),
TP_ARGS(dev, domain),

TP_STRUCT__entry(
__field( dev_t, dev )
__array( char, domain, DOMAIN_LEN )
),

TP_fast_assign(
__entry->dev = disk_devt(q->disk);
__entry->dev = dev;
strlcpy(__entry->domain, domain, sizeof(__entry->domain));
),

Expand Down

0 comments on commit c411080

Please sign in to comment.