aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/uipc_shm.c
diff options
context:
space:
mode:
authorWill Andrews <will@FreeBSD.org>2015-04-11 18:51:41 +0000
committerWill Andrews <will@FreeBSD.org>2015-04-11 18:51:41 +0000
commit6311d7aaf06d6618cda0e295fb873cb693380279 (patch)
tree59c90b0e4377af2dd77d02ae30c07e6353d1392f /sys/kern/uipc_shm.c
parente6ef49ea681768dc84acf67dcb07ea38861a7750 (diff)
downloadsrc-6311d7aaf06d6618cda0e295fb873cb693380279.tar.gz
src-6311d7aaf06d6618cda0e295fb873cb693380279.zip
uiomove_object_page(): Avoid instantiating pages in sparse regions on reads.
Check whether the page being requested is either resident or on swap. If not, read from the zero_region instead of instantiating an unnecessary page. This avoids consuming memory for sparse files on tmpfs, when they are read by applications that do not use SEEK_HOLE/SEEK_DATA (which is most of them). Reviewed by: kib MFC after: 1 week Sponsored by: Spectra Logic
Notes
Notes: svn path=/head/; revision=281442
Diffstat (limited to 'sys/kern/uipc_shm.c')
-rw-r--r--sys/kern/uipc_shm.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index 14347d11602f..8410ed9b894a 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -163,6 +163,17 @@ uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio)
VM_OBJECT_WLOCK(obj);
/*
+ * Read I/O without either a corresponding resident page or swap
+ * page: use zero_region. This is intended to avoid instantiating
+ * pages on read from a sparse region.
+ */
+ if (uio->uio_rw == UIO_READ && vm_page_lookup(obj, idx) == NULL &&
+ !vm_pager_has_page(obj, idx, NULL, NULL)) {
+ VM_OBJECT_WUNLOCK(obj);
+ return (uiomove(__DECONST(void *, zero_region), len, uio));
+ }
+
+ /*
* Parallel reads of the page content from disk are prevented
* by exclusive busy.
*