[rfc] small bioq patch

Maksim Yevmenkin emax at freebsd.org
Fri Oct 11 18:17:27 UTC 2013


hello,

i would like to submit the attached bioq patch for review and
comments. this is proof of concept. it helps with smoothing disk read
service times and arrear to eliminates outliers. please see attached
pictures (about a week worth of data)

- c034 "control" unmodified system
- c044 patched system

graphs show max/avg disk read service times for both systems across 36
spinning drives. both systems are relatively busy serving production
traffic (about 10 Gbps at peak). grey shaded areas on the graphs
represent time when systems are refreshing their content, i.e. disks
are both reading and writing at the same time.

thanks,
max
-------------- next part --------------
Index: branches/freebsd10/src/sys/kern/subr_disk.c
===================================================================
diff -u -N -r2284 -r2698
--- branches/freebsd10/src/sys/kern/subr_disk.c	(.../subr_disk.c)	(revision 2284)
+++ branches/freebsd10/src/sys/kern/subr_disk.c	(.../subr_disk.c)	(revision 2698)
@@ -21,8 +21,13 @@
 #include <sys/bio.h>
 #include <sys/conf.h>
 #include <sys/disk.h>
+#include <sys/sysctl.h>
 #include <geom/geom_disk.h>
 
+static int bioq_batchsize = 128;
+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
@@ -150,6 +155,8 @@
 	TAILQ_INIT(&head->queue);
 	head->last_offset = 0;
 	head->insert_point = NULL;
+	head->total = 0;
+	head->batched = 0;
 }
 
 void
@@ -163,6 +170,7 @@
 		head->insert_point = NULL;
 
 	TAILQ_REMOVE(&head->queue, bp, bio_queue);
+	head->total--;
 }
 
 void
@@ -181,13 +189,16 @@
 	if (head->insert_point == NULL)
 		head->last_offset = bp->bio_offset;
 	TAILQ_INSERT_HEAD(&head->queue, bp, bio_queue);
+	head->total++;
 }
 
 void
 bioq_insert_tail(struct bio_queue_head *head, struct bio *bp)
 {
 
 	TAILQ_INSERT_TAIL(&head->queue, bp, bio_queue);
+	head->total++;
+	head->batched = 0;
 	head->insert_point = bp;
 	head->last_offset = bp->bio_offset;
 }
@@ -246,6 +257,11 @@
 		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);
@@ -264,4 +280,7 @@
 		TAILQ_INSERT_HEAD(&head->queue, bp, bio_queue);
 	else
 		TAILQ_INSERT_AFTER(&head->queue, prev, bp, bio_queue);
+
+	head->total++;
+	head->batched++;
 }
Index: branches/freebsd10/src/sys/sys/bio.h
===================================================================
diff -u -N -r2284 -r2698
--- branches/freebsd10/src/sys/sys/bio.h	(.../bio.h)	(revision 2284)
+++ branches/freebsd10/src/sys/sys/bio.h	(.../bio.h)	(revision 2698)
@@ -129,6 +129,8 @@
 	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;


More information about the freebsd-current mailing list