Module Name:    src
Committed By:   jdolecek
Date:           Sat May 19 15:18:02 UTC 2018

Modified Files:
        src/sys/uvm: uvm_readahead.c

Log Message:
adjust heuristics for read-ahead to skip the full read-ahead when last page of
the range is already cached; this speeds up I/O from cache, since it avoids
the lookup and allocation overhead

on my system I observed 4.5% - 15% improvement for cached I/O - from 2.2 GB/s to
2.3 GB/s for cached reads using non-direct UBC, and from 5.6 GB/s to 6.5 GB/s
for UBC using direct map

part of PR kern/53124


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/uvm/uvm_readahead.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/uvm/uvm_readahead.c
diff -u src/sys/uvm/uvm_readahead.c:1.9 src/sys/uvm/uvm_readahead.c:1.10
--- src/sys/uvm/uvm_readahead.c:1.9	Fri Mar 30 07:22:59 2018
+++ src/sys/uvm/uvm_readahead.c	Sat May 19 15:18:02 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_readahead.c,v 1.9 2018/03/30 07:22:59 mlelstv Exp $	*/
+/*	$NetBSD: uvm_readahead.c,v 1.10 2018/05/19 15:18:02 jdolecek Exp $	*/
 
 /*-
  * Copyright (c)2003, 2005, 2009 YAMAMOTO Takashi,
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_readahead.c,v 1.9 2018/03/30 07:22:59 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_readahead.c,v 1.10 2018/05/19 15:18:02 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/pool.h>
@@ -125,6 +125,23 @@ ra_startio(struct uvm_object *uobj, off_
 
 	DPRINTF(("%s: uobj=%p, off=%" PRIu64 ", endoff=%" PRIu64 "\n",
 	    __func__, uobj, off, endoff));
+
+	/*
+	 * Don't issue read-ahead if the last page of the range is already cached.
+	 * The assumption is that since the access is sequential, the intermediate
+	 * pages would have similar LRU stats, and hence likely to be still in cache
+	 * too. This speeds up I/O using cache, since it avoids lookups and temporary
+	 * allocations done by full pgo_get.
+	 */
+	mutex_enter(uobj->vmobjlock);
+	struct vm_page *pg = uvm_pagelookup(uobj, trunc_page(endoff - 1));
+	mutex_exit(uobj->vmobjlock);
+	if (pg != NULL) {
+		DPRINTF(("%s:  off=%" PRIu64 ", sz=%zu already cached\n",
+		    __func__, off, sz));
+		return endoff;
+	}
+
 	off = trunc_page(off);
 	while (off < endoff) {
 		const size_t chunksize = RA_IOCHUNK;
@@ -147,7 +164,7 @@ ra_startio(struct uvm_object *uobj, off_
 
 		mutex_enter(uobj->vmobjlock);
 		error = (*uobj->pgops->pgo_get)(uobj, off, NULL,
-		    &npages, 0, VM_PROT_READ, UVM_ADV_RANDOM, 0);
+		    &npages, 0, VM_PROT_READ, UVM_ADV_RANDOM, PGO_NOTIMESTAMP);
 		DPRINTF(("%s:  off=%" PRIu64 ", bytelen=%zu -> %d\n",
 		    __func__, off, bytelen, error));
 		if (error != 0 && error != EBUSY) {

Reply via email to