summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2013-05-07 08:16:21 +0000
committerscottl <scottl@FreeBSD.org>2013-05-07 08:16:21 +0000
commita5718800b18e9b041aea3c13a2c790d9da75ed17 (patch)
treef48f275b48203a9c6a0b01c2f0d6735f550be109 /sys/kern
parent7218a7cacea670cef5babb5a6d86ab5afbbce563 (diff)
downloadFreeBSD-src-a5718800b18e9b041aea3c13a2c790d9da75ed17.zip
FreeBSD-src-a5718800b18e9b041aea3c13a2c790d9da75ed17.tar.gz
Add a sysctl vfs.read_min to complement the exiting vfs.read_max. It
defaults to 1, meaning that it's off. When read-ahead is enabled on a file, the vfs cluster code deliberately breaks a read into 2 I/O transactions; one to satisfy the actual read, and one to perform read-ahead. This makes sense in low-latency circumstances, but often produces unbalanced i/o transactions that penalize disks. By setting vfs.read_min, we can tell the algorithm to fetch a larger transaction that what we asked for, achieving the same effect as the read-ahead but without the doubled, unbalanced transaction and the slightly lower latency. This significantly helps our workloads with video streaming. Submitted by: emax Reviewed by: kib Obtained from: Netflix
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_cluster.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c
index 91a0443..d619960 100644
--- a/sys/kern/vfs_cluster.c
+++ b/sys/kern/vfs_cluster.c
@@ -76,6 +76,10 @@ static int read_max = 64;
SYSCTL_INT(_vfs, OID_AUTO, read_max, CTLFLAG_RW, &read_max, 0,
"Cluster read-ahead max block count");
+static int read_min = 1;
+SYSCTL_INT(_vfs, OID_AUTO, read_min, CTLFLAG_RW, &read_min, 0,
+ "Cluster read min block count");
+
/* Page expended to mark partially backed buffers */
extern vm_page_t bogus_page;
@@ -166,6 +170,7 @@ cluster_read(struct vnode *vp, u_quad_t filesize, daddr_t lblkno, long size,
} else {
off_t firstread = bp->b_offset;
int nblks;
+ long minread;
KASSERT(bp->b_offset != NOOFFSET,
("cluster_read: no buffer offset"));
@@ -173,6 +178,13 @@ cluster_read(struct vnode *vp, u_quad_t filesize, daddr_t lblkno, long size,
ncontig = 0;
/*
+ * Adjust totread if needed
+ */
+ minread = read_min * size;
+ if (minread > totread)
+ totread = minread;
+
+ /*
* Compute the total number of blocks that we should read
* synchronously.
*/
OpenPOWER on IntegriCloud