summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_reserv.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2013-05-12 16:50:18 +0000
committeralc <alc@FreeBSD.org>2013-05-12 16:50:18 +0000
commit7d20e37fb658b0e2cd7f3c13dac8022e0e866a21 (patch)
treef0a16a6164c2636942cacaa989a08f31dafdb3f4 /sys/vm/vm_reserv.c
parent6907881cb814953c545475a8a63e3afc402bd547 (diff)
downloadFreeBSD-src-7d20e37fb658b0e2cd7f3c13dac8022e0e866a21.zip
FreeBSD-src-7d20e37fb658b0e2cd7f3c13dac8022e0e866a21.tar.gz
Refactor vm_page_alloc()'s interactions with vm_reserv_alloc_page() and
vm_page_insert() so that (1) vm_radix_lookup_le() is never called while the free page queues lock is held and (2) vm_radix_lookup_le() is called at most once. This change reduces the average time that the free page queues lock is held by vm_page_alloc() as well as vm_page_alloc()'s average overall running time. Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'sys/vm/vm_reserv.c')
-rw-r--r--sys/vm/vm_reserv.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/sys/vm/vm_reserv.c b/sys/vm/vm_reserv.c
index 4d36385..c264a76 100644
--- a/sys/vm/vm_reserv.c
+++ b/sys/vm/vm_reserv.c
@@ -476,12 +476,15 @@ found:
/*
* Allocates a page from an existing or newly-created reservation.
*
+ * The page "mpred" must immediately precede the offset "pindex" within the
+ * specified object.
+ *
* The object and free page queue must be locked.
*/
vm_page_t
-vm_reserv_alloc_page(vm_object_t object, vm_pindex_t pindex)
+vm_reserv_alloc_page(vm_object_t object, vm_pindex_t pindex, vm_page_t mpred)
{
- vm_page_t m, mpred, msucc;
+ vm_page_t m, msucc;
vm_pindex_t first, leftcap, rightcap;
vm_reserv_t rv;
@@ -498,10 +501,12 @@ vm_reserv_alloc_page(vm_object_t object, vm_pindex_t pindex)
/*
* Look for an existing reservation.
*/
- mpred = vm_radix_lookup_le(&object->rtree, pindex);
if (mpred != NULL) {
+ KASSERT(mpred->object == object ||
+ (mpred->flags & PG_SLAB) != 0,
+ ("vm_reserv_alloc_page: object doesn't contain mpred"));
KASSERT(mpred->pindex < pindex,
- ("vm_reserv_alloc_page: pindex already allocated"));
+ ("vm_reserv_alloc_page: mpred doesn't precede pindex"));
rv = vm_reserv_from_page(mpred);
if (rv->object == object && vm_reserv_has_pindex(rv, pindex))
goto found;
@@ -510,7 +515,7 @@ vm_reserv_alloc_page(vm_object_t object, vm_pindex_t pindex)
msucc = TAILQ_FIRST(&object->memq);
if (msucc != NULL) {
KASSERT(msucc->pindex > pindex,
- ("vm_reserv_alloc_page: pindex already allocated"));
+ ("vm_reserv_alloc_page: msucc doesn't succeed pindex"));
rv = vm_reserv_from_page(msucc);
if (rv->object == object && vm_reserv_has_pindex(rv, pindex))
goto found;
OpenPOWER on IntegriCloud