aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2022-10-20 13:15:46 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2022-12-09 12:15:37 +0000
commitec201dddfbddd3a77dd3f3afc9b007d0e13e7ad1 (patch)
treef68dce42c2c18dc152b4006decac0fde6107f364
parentd537d1f12e8829faccd395115193b03b578f1176 (diff)
downloadsrc-ec201dddfbddd3a77dd3f3afc9b007d0e13e7ad1.tar.gz
src-ec201dddfbddd3a77dd3f3afc9b007d0e13e7ad1.zip
vm_pager: add method to veto page allocation
Reviewed by: markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D37097
-rw-r--r--sys/vm/vm_fault.c4
-rw-r--r--sys/vm/vm_page.c4
-rw-r--r--sys/vm/vm_pager.c1
-rw-r--r--sys/vm/vm_pager.h11
4 files changed, 20 insertions, 0 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 8f30c5b93828..959e67b88a38 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -1212,6 +1212,10 @@ vm_fault_allocate(struct faultstate *fs)
#if VM_NRESERVLEVEL > 0
vm_object_color(fs->object, atop(fs->vaddr) - fs->pindex);
#endif
+ if (!vm_pager_can_alloc_page(fs->object, fs->pindex)) {
+ unlock_and_deallocate(fs);
+ return (FAULT_FAILURE);
+ }
fs->m = vm_page_alloc(fs->object, fs->pindex,
P_KILLED(curproc) ? VM_ALLOC_SYSTEM : 0);
}
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 20238e0ad807..2b7bc6a5b66e 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -2027,6 +2027,8 @@ vm_page_alloc_domain_after(vm_object_t object, vm_pindex_t pindex, int domain,
flags = 0;
m = NULL;
+ if (!vm_pager_can_alloc_page(object, pindex))
+ return (NULL);
again:
#if VM_NRESERVLEVEL > 0
/*
@@ -4698,6 +4700,8 @@ retrylookup:
*mp = NULL;
return (VM_PAGER_FAIL);
} else if ((m = vm_page_alloc(object, pindex, pflags)) == NULL) {
+ if (!vm_pager_can_alloc_page(object, pindex))
+ return (VM_PAGER_AGAIN);
goto retrylookup;
}
diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c
index 36ce380dedbc..08ce98ab5dbd 100644
--- a/sys/vm/vm_pager.c
+++ b/sys/vm/vm_pager.c
@@ -432,6 +432,7 @@ vm_pager_alloc_dyn_type(struct pagerops *ops, int base_type)
FIX(freespace);
FIX(page_inserted);
FIX(page_removed);
+ FIX(can_alloc_page);
#undef FIX
}
pagertab[res] = ops; /* XXXKIB should be rel, but acq is too much */
diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h
index 5917bf651760..0e248d871250 100644
--- a/sys/vm/vm_pager.h
+++ b/sys/vm/vm_pager.h
@@ -71,6 +71,7 @@ typedef void pgo_freespace_t(vm_object_t object, vm_pindex_t start,
vm_size_t size);
typedef void pgo_page_inserted_t(vm_object_t object, vm_page_t m);
typedef void pgo_page_removed_t(vm_object_t object, vm_page_t m);
+typedef boolean_t pgo_can_alloc_page_t(vm_object_t object, vm_pindex_t pindex);
struct pagerops {
int pgo_kvme_type;
@@ -91,6 +92,7 @@ struct pagerops {
pgo_freespace_t *pgo_freespace;
pgo_page_inserted_t *pgo_page_inserted;
pgo_page_removed_t *pgo_page_removed;
+ pgo_can_alloc_page_t *pgo_can_alloc_page;
};
extern const struct pagerops defaultpagerops;
@@ -273,6 +275,15 @@ vm_pager_page_removed(vm_object_t object, vm_page_t m)
method(object, m);
}
+static __inline bool
+vm_pager_can_alloc_page(vm_object_t object, vm_pindex_t pindex)
+{
+ pgo_can_alloc_page_t *method;
+
+ method = pagertab[object->type]->pgo_can_alloc_page;
+ return (method != NULL ? method(object, pindex) : true);
+}
+
int vm_pager_alloc_dyn_type(struct pagerops *ops, int base_type);
void vm_pager_free_dyn_type(objtype_t type);