summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2001-10-31 03:06:33 +0000
committerdillon <dillon@FreeBSD.org>2001-10-31 03:06:33 +0000
commitb11fa1d14dcd0c423c44976ff988b593de218a89 (patch)
treea1f4c581b424a7ec9997c2852806b620613051fe /sys/amd64
parentde8bc4ba10fb07aa68c4cd0d79b35529c6b1b958 (diff)
downloadFreeBSD-src-b11fa1d14dcd0c423c44976ff988b593de218a89.zip
FreeBSD-src-b11fa1d14dcd0c423c44976ff988b593de218a89.tar.gz
Don't let pmap_object_init_pt() exhaust all available free pages
(allocating pv entries w/ zalloci) when called in a loop due to an madvise(). It is possible to completely exhaust the free page list and cause a system panic when an expected allocation fails.
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/pmap.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 5912074..edd0758 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -2546,7 +2546,7 @@ retry:
psize = i386_btop(size);
if ((object->type != OBJT_VNODE) ||
- (limit && (psize > MAX_INIT_PT) &&
+ ((limit & MAP_PREFAULT_PARTIAL) && (psize > MAX_INIT_PT) &&
(object->resident_page_count > MAX_INIT_PT))) {
return;
}
@@ -2577,6 +2577,14 @@ retry:
if (tmpidx >= psize) {
continue;
}
+ /*
+ * don't allow an madvise to blow away our really
+ * free pages allocating pv entries.
+ */
+ if ((limit & MAP_PREFAULT_MADVISE) &&
+ cnt.v_free_count < cnt.v_free_reserved) {
+ break;
+ }
if (((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
(p->busy == 0) &&
(p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
@@ -2595,6 +2603,14 @@ retry:
* else lookup the pages one-by-one.
*/
for (tmpidx = 0; tmpidx < psize; tmpidx += 1) {
+ /*
+ * don't allow an madvise to blow away our really
+ * free pages allocating pv entries.
+ */
+ if ((limit & MAP_PREFAULT_MADVISE) &&
+ cnt.v_free_count < cnt.v_free_reserved) {
+ break;
+ }
p = vm_page_lookup(object, tmpidx + pindex);
if (p &&
((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
OpenPOWER on IntegriCloud