From a971acbc25f7b9edfcc7f6367bfc69a64296b5da Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 13 Jun 2018 16:48:07 +0000 Subject: [PATCH] Implement a 'car limit' for bioq. Allow one to implement a 'car limit' for bioq_disksort. debug.bioq_batchsize sets the size of car limit. Every time we queue that many requests, we start over so that we limit the latency for requests when the software queue depths are large. A value of '0', the default, means to revert to the old behavior. Sponsored by: Netflix --- sys/kern/subr_disk.c | 18 ++++++++++++++++++ sys/sys/bio.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index 9b9b572916b..328111337c9 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -23,8 +23,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +static int bioq_batchsize = 0; +SYSCTL_INT(_debug, OID_AUTO, bioq_batchsize, CTLFLAG_RW, + &bioq_batchsize, 0, "BIOQ batch size"); + /*- * Disk error is the preface to plaintive error messages * about failing disk transfers. It prints messages of the form @@ -152,6 +157,8 @@ bioq_init(struct bio_queue_head *head) TAILQ_INIT(&head->queue); head->last_offset = 0; head->insert_point = NULL; + head->total = 0; + head->batched = 0; } void @@ -165,6 +172,7 @@ bioq_remove(struct bio_queue_head *head, struct bio *bp) head->insert_point = NULL; TAILQ_REMOVE(&head->queue, bp, bio_queue); + head->total--; } void @@ -183,6 +191,8 @@ bioq_insert_head(struct bio_queue_head *head, struct bio *bp) if (head->insert_point == NULL) head->last_offset = bp->bio_offset; TAILQ_INSERT_HEAD(&head->queue, bp, bio_queue); + head->total++; + head->batched = 0; } void @@ -190,6 +200,7 @@ bioq_insert_tail(struct bio_queue_head *head, struct bio *bp) { TAILQ_INSERT_TAIL(&head->queue, bp, bio_queue); + head->total++; head->insert_point = bp; head->last_offset = bp->bio_offset; } @@ -248,6 +259,11 @@ bioq_disksort(struct bio_queue_head *head, struct bio *bp) return; } + if (bioq_batchsize > 0 && head->batched > bioq_batchsize) { + bioq_insert_tail(head, bp); + return; + } + prev = NULL; key = bioq_bio_key(head, bp); cur = TAILQ_FIRST(&head->queue); @@ -266,4 +282,6 @@ bioq_disksort(struct bio_queue_head *head, struct bio *bp) TAILQ_INSERT_HEAD(&head->queue, bp, bio_queue); else TAILQ_INSERT_AFTER(&head->queue, prev, bp, bio_queue); + head->total++; + head->batched++; } diff --git a/sys/sys/bio.h b/sys/sys/bio.h index 0691834e3a1..1dab615578e 100644 --- a/sys/sys/bio.h +++ b/sys/sys/bio.h @@ -138,6 +138,8 @@ struct bio_queue_head { TAILQ_HEAD(bio_queue, bio) queue; off_t last_offset; struct bio *insert_point; + int total; + int batched; }; extern struct vm_map *bio_transient_map;