diff options
author | Will Andrews <will@FreeBSD.org> | 2015-04-11 18:51:41 +0000 |
---|---|---|
committer | Will Andrews <will@FreeBSD.org> | 2015-04-11 18:51:41 +0000 |
commit | 6311d7aaf06d6618cda0e295fb873cb693380279 (patch) | |
tree | 59c90b0e4377af2dd77d02ae30c07e6353d1392f /sys/kern/uipc_shm.c | |
parent | e6ef49ea681768dc84acf67dcb07ea38861a7750 (diff) | |
download | src-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.c | 11 |
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. * |